ia64/linux-2.6.18-xen.hg

changeset 5:405dae994591

Imported patch linux-2.6.19-rc1-kexec-move_segment_code-x86_64.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 1c0aeb8749d2
children 4763065c587c
files arch/x86_64/kernel/machine_kexec.c arch/x86_64/kernel/relocate_kernel.S
line diff
     1.1 --- a/arch/x86_64/kernel/machine_kexec.c	Mon Jun 04 10:05:23 2007 +0100
     1.2 +++ b/arch/x86_64/kernel/machine_kexec.c	Mon Jun 04 10:05:23 2007 +0100
     1.3 @@ -112,47 +112,6 @@ static int init_pgtable(struct kimage *i
     1.4   	return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT);
     1.5  }
     1.6  
     1.7 -static void set_idt(void *newidt, u16 limit)
     1.8 -{
     1.9 -	struct desc_ptr curidt;
    1.10 -
    1.11 -	/* x86-64 supports unaliged loads & stores */
    1.12 -	curidt.size    = limit;
    1.13 -	curidt.address = (unsigned long)newidt;
    1.14 -
    1.15 -	__asm__ __volatile__ (
    1.16 -		"lidtq %0\n"
    1.17 -		: : "m" (curidt)
    1.18 -		);
    1.19 -};
    1.20 -
    1.21 -
    1.22 -static void set_gdt(void *newgdt, u16 limit)
    1.23 -{
    1.24 -	struct desc_ptr curgdt;
    1.25 -
    1.26 -	/* x86-64 supports unaligned loads & stores */
    1.27 -	curgdt.size    = limit;
    1.28 -	curgdt.address = (unsigned long)newgdt;
    1.29 -
    1.30 -	__asm__ __volatile__ (
    1.31 -		"lgdtq %0\n"
    1.32 -		: : "m" (curgdt)
    1.33 -		);
    1.34 -};
    1.35 -
    1.36 -static void load_segments(void)
    1.37 -{
    1.38 -	__asm__ __volatile__ (
    1.39 -		"\tmovl %0,%%ds\n"
    1.40 -		"\tmovl %0,%%es\n"
    1.41 -		"\tmovl %0,%%ss\n"
    1.42 -		"\tmovl %0,%%fs\n"
    1.43 -		"\tmovl %0,%%gs\n"
    1.44 -		: : "a" (__KERNEL_DS) : "memory"
    1.45 -		);
    1.46 -}
    1.47 -
    1.48  int machine_kexec_prepare(struct kimage *image)
    1.49  {
    1.50  	unsigned long start_pgtable;
    1.51 @@ -209,23 +168,6 @@ NORET_TYPE void machine_kexec(struct kim
    1.52  	page_list[PA_TABLE_PAGE] =
    1.53  	  (unsigned long)__pa(page_address(image->control_code_page));
    1.54  
    1.55 -	/* The segment registers are funny things, they have both a
    1.56 -	 * visible and an invisible part.  Whenever the visible part is
    1.57 -	 * set to a specific selector, the invisible part is loaded
    1.58 -	 * with from a table in memory.  At no other time is the
    1.59 -	 * descriptor table in memory accessed.
    1.60 -	 *
    1.61 -	 * I take advantage of this here by force loading the
    1.62 -	 * segments, before I zap the gdt with an invalid value.
    1.63 -	 */
    1.64 -	load_segments();
    1.65 -	/* The gdt & idt are now invalid.
    1.66 -	 * If you want to load them you must set up your own idt & gdt.
    1.67 -	 */
    1.68 -	set_gdt(phys_to_virt(0),0);
    1.69 -	set_idt(phys_to_virt(0),0);
    1.70 -
    1.71 -	/* now call it */
    1.72  	relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
    1.73  			image->start);
    1.74  }
     2.1 --- a/arch/x86_64/kernel/relocate_kernel.S	Mon Jun 04 10:05:23 2007 +0100
     2.2 +++ b/arch/x86_64/kernel/relocate_kernel.S	Mon Jun 04 10:05:23 2007 +0100
     2.3 @@ -159,13 +159,39 @@ relocate_new_kernel:
     2.4  	movq	PTR(PA_PGD)(%rsi), %r9
     2.5  	movq	%r9, %cr3
     2.6  
     2.7 +	/* setup idt */
     2.8 +	movq    %r8, %rax
     2.9 +	addq    $(idt_80 - relocate_kernel), %rax
    2.10 +	lidtq   (%rax)
    2.11 +
    2.12 +	/* setup gdt */
    2.13 +	movq    %r8, %rax
    2.14 +	addq    $(gdt - relocate_kernel), %rax
    2.15 +	movq    %r8, %r9
    2.16 +	addq    $((gdt_80 - relocate_kernel) + 2), %r9
    2.17 +	movq    %rax, (%r9)
    2.18 +
    2.19 +	movq    %r8, %rax
    2.20 +	addq    $(gdt_80 - relocate_kernel), %rax
    2.21 +	lgdtq   (%rax)
    2.22 +
    2.23 +	/* setup data segment registers */
    2.24 +	xorl	%eax, %eax
    2.25 +	movl    %eax, %ds
    2.26 +	movl    %eax, %es
    2.27 +	movl    %eax, %fs
    2.28 +	movl    %eax, %gs
    2.29 +	movl    %eax, %ss
    2.30 +	
    2.31  	/* setup a new stack at the end of the physical control page */
    2.32  	lea	4096(%r8), %rsp
    2.33  
    2.34 -	/* jump to identity mapped page */
    2.35 -	addq	$(identity_mapped - relocate_kernel), %r8
    2.36 -	pushq	%r8
    2.37 -	ret
    2.38 +	/* load new code segment and jump to identity mapped page */
    2.39 +	movq	%r8, %rax
    2.40 +	addq    $(identity_mapped - relocate_kernel), %rax
    2.41 +	pushq	$(gdt_cs - gdt)
    2.42 +	pushq	%rax
    2.43 +	lretq
    2.44  
    2.45  identity_mapped:
    2.46  	/* store the start address on the stack */
    2.47 @@ -272,5 +298,19 @@ 3:
    2.48  	xorq	%r13, %r13
    2.49  	xorq	%r14, %r14
    2.50  	xorq	%r15, %r15
    2.51 +	ret
    2.52  
    2.53 -	ret
    2.54 +	.align  16
    2.55 +gdt:
    2.56 +	.quad	0x0000000000000000	/* NULL descriptor */
    2.57 +gdt_cs:
    2.58 +	.quad   0x00af9a000000ffff
    2.59 +gdt_end:
    2.60 +
    2.61 +gdt_80:
    2.62 +	.word	gdt_end - gdt - 1	/* limit */
    2.63 +	.quad	0			/* base - filled in by code above */
    2.64 +
    2.65 +idt_80:
    2.66 +	.word	0			/* limit */
    2.67 +	.quad	0			/* base */