ia64/linux-2.6.18-xen.hg

changeset 3:948d16bbacc2

Imported patch linux-2.6.19-rc1-kexec-move_segment_code-i386.patch from xen-unstable.hg 15200:bd3d6b4c52ec
author Ian Campbell <ian.campbell@xensource.com>
date Mon Jun 04 10:05:23 2007 +0100 (2007-06-04)
parents 07baeb6664de
children 1c0aeb8749d2
files arch/i386/kernel/machine_kexec.c arch/i386/kernel/relocate_kernel.S
line diff
     1.1 --- a/arch/i386/kernel/machine_kexec.c	Mon Jun 04 10:05:23 2007 +0100
     1.2 +++ b/arch/i386/kernel/machine_kexec.c	Mon Jun 04 10:05:23 2007 +0100
     1.3 @@ -28,48 +28,6 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
     1.4  static u32 kexec_pte0[1024] PAGE_ALIGNED;
     1.5  static u32 kexec_pte1[1024] PAGE_ALIGNED;
     1.6  
     1.7 -static void set_idt(void *newidt, __u16 limit)
     1.8 -{
     1.9 -	struct Xgt_desc_struct curidt;
    1.10 -
    1.11 -	/* ia32 supports unaliged loads & stores */
    1.12 -	curidt.size    = limit;
    1.13 -	curidt.address = (unsigned long)newidt;
    1.14 -
    1.15 -	load_idt(&curidt);
    1.16 -};
    1.17 -
    1.18 -
    1.19 -static void set_gdt(void *newgdt, __u16 limit)
    1.20 -{
    1.21 -	struct Xgt_desc_struct curgdt;
    1.22 -
    1.23 -	/* ia32 supports unaligned loads & stores */
    1.24 -	curgdt.size    = limit;
    1.25 -	curgdt.address = (unsigned long)newgdt;
    1.26 -
    1.27 -	load_gdt(&curgdt);
    1.28 -};
    1.29 -
    1.30 -static void load_segments(void)
    1.31 -{
    1.32 -#define __STR(X) #X
    1.33 -#define STR(X) __STR(X)
    1.34 -
    1.35 -	__asm__ __volatile__ (
    1.36 -		"\tljmp $"STR(__KERNEL_CS)",$1f\n"
    1.37 -		"\t1:\n"
    1.38 -		"\tmovl $"STR(__KERNEL_DS)",%%eax\n"
    1.39 -		"\tmovl %%eax,%%ds\n"
    1.40 -		"\tmovl %%eax,%%es\n"
    1.41 -		"\tmovl %%eax,%%fs\n"
    1.42 -		"\tmovl %%eax,%%gs\n"
    1.43 -		"\tmovl %%eax,%%ss\n"
    1.44 -		::: "eax", "memory");
    1.45 -#undef STR
    1.46 -#undef __STR
    1.47 -}
    1.48 -
    1.49  /*
    1.50   * A architecture hook called to validate the
    1.51   * proposed image and prepare the control pages
    1.52 @@ -126,23 +84,6 @@ NORET_TYPE void machine_kexec(struct kim
    1.53  	page_list[PA_PTE_1] = __pa(kexec_pte1);
    1.54  	page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
    1.55  
    1.56 -	/* The segment registers are funny things, they have both a
    1.57 -	 * visible and an invisible part.  Whenever the visible part is
    1.58 -	 * set to a specific selector, the invisible part is loaded
    1.59 -	 * with from a table in memory.  At no other time is the
    1.60 -	 * descriptor table in memory accessed.
    1.61 -	 *
    1.62 -	 * I take advantage of this here by force loading the
    1.63 -	 * segments, before I zap the gdt with an invalid value.
    1.64 -	 */
    1.65 -	load_segments();
    1.66 -	/* The gdt & idt are now invalid.
    1.67 -	 * If you want to load them you must set up your own idt & gdt.
    1.68 -	 */
    1.69 -	set_gdt(phys_to_virt(0),0);
    1.70 -	set_idt(phys_to_virt(0),0);
    1.71 -
    1.72 -	/* now call it */
    1.73  	relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
    1.74  			image->start, cpu_has_pae);
    1.75  }
     2.1 --- a/arch/i386/kernel/relocate_kernel.S	Mon Jun 04 10:05:23 2007 +0100
     2.2 +++ b/arch/i386/kernel/relocate_kernel.S	Mon Jun 04 10:05:23 2007 +0100
     2.3 @@ -154,14 +154,45 @@ relocate_new_kernel:
     2.4  	movl	PTR(PA_PGD)(%ebp), %eax
     2.5  	movl	%eax, %cr3
     2.6  
     2.7 +	/* setup idt */
     2.8 +	movl	%edi, %eax
     2.9 +	addl	$(idt_48 - relocate_kernel), %eax
    2.10 +	lidtl	(%eax)
    2.11 +
    2.12 +	/* setup gdt */
    2.13 +	movl	%edi, %eax
    2.14 +	addl	$(gdt - relocate_kernel), %eax
    2.15 +	movl	%edi, %esi
    2.16 +	addl	$((gdt_48 - relocate_kernel) + 2), %esi
    2.17 +	movl	%eax, (%esi)
    2.18 +	
    2.19 +	movl	%edi, %eax
    2.20 +	addl	$(gdt_48 - relocate_kernel), %eax
    2.21 +	lgdtl	(%eax)
    2.22 +
    2.23 +	/* setup data segment registers */
    2.24 +	mov	$(gdt_ds - gdt), %eax
    2.25 +	mov	%eax, %ds
    2.26 +	mov	%eax, %es
    2.27 +	mov	%eax, %fs
    2.28 +	mov	%eax, %gs
    2.29 +	mov	%eax, %ss
    2.30 +	
    2.31  	/* setup a new stack at the end of the physical control page */
    2.32  	lea	4096(%edi), %esp
    2.33  
    2.34 -	/* jump to identity mapped page */
    2.35 -	movl    %edi, %eax
    2.36 -	addl    $(identity_mapped - relocate_kernel), %eax
    2.37 -	pushl   %eax
    2.38 -	ret
    2.39 +	/* load new code segment and jump to identity mapped page */
    2.40 +	movl	%edi, %esi
    2.41 +	xorl	%eax, %eax
    2.42 +	pushl	%eax
    2.43 +	pushl	%esi
    2.44 +	pushl	%eax
    2.45 +	movl	$(gdt_cs - gdt), %eax
    2.46 +	pushl	%eax	
    2.47 +	movl	%edi, %eax
    2.48 +	addl	$(identity_mapped - relocate_kernel),%eax
    2.49 +	pushl	%eax
    2.50 +	iretl
    2.51  
    2.52  identity_mapped:
    2.53  	/* store the start address on the stack */
    2.54 @@ -250,3 +281,20 @@ 3:
    2.55  	xorl    %edi, %edi
    2.56  	xorl    %ebp, %ebp
    2.57  	ret
    2.58 +
    2.59 +	.align	16
    2.60 +gdt:
    2.61 +	.quad	0x0000000000000000	/* NULL descriptor */
    2.62 +gdt_cs:	
    2.63 +	.quad	0x00cf9a000000ffff	/* kernel 4GB code at 0x00000000 */
    2.64 +gdt_ds:
    2.65 +	.quad	0x00cf92000000ffff	/* kernel 4GB data at 0x00000000 */
    2.66 +gdt_end:
    2.67 +	
    2.68 +gdt_48:
    2.69 +	.word	gdt_end - gdt - 1	/* limit */
    2.70 +	.long	0			/* base - filled in by code above */
    2.71 +
    2.72 +idt_48:
    2.73 +	.word	0			/* limit */
    2.74 +	.long	0			/* base */