[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] Imported patch linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch from xen-unstable.hg 15200:bd3d6b4c52ec
# HG changeset patch # User Ian Campbell <ian.campbell@xxxxxxxxxxxxx> # Date 1180947923 -3600 # Node ID 405dae994591a785c16c59e50658bea7814b7000 # Parent 1c0aeb8749d2c27475d33143b28e53dadc154eb3 Imported patch linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch from xen-unstable.hg 15200:bd3d6b4c52ec --- arch/x86_64/kernel/machine_kexec.c | 58 ----------------------------------- arch/x86_64/kernel/relocate_kernel.S | 50 +++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 63 deletions(-) diff -r 1c0aeb8749d2 -r 405dae994591 arch/x86_64/kernel/machine_kexec.c --- a/arch/x86_64/kernel/machine_kexec.c Mon Jun 04 10:05:23 2007 +0100 +++ b/arch/x86_64/kernel/machine_kexec.c Mon Jun 04 10:05:23 2007 +0100 @@ -112,47 +112,6 @@ static int init_pgtable(struct kimage *i return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT); } -static void set_idt(void *newidt, u16 limit) -{ - struct desc_ptr curidt; - - /* x86-64 supports unaliged loads & stores */ - curidt.size = limit; - curidt.address = (unsigned long)newidt; - - __asm__ __volatile__ ( - "lidtq %0\n" - : : "m" (curidt) - ); -}; - - -static void set_gdt(void *newgdt, u16 limit) -{ - struct desc_ptr curgdt; - - /* x86-64 supports unaligned loads & stores */ - curgdt.size = limit; - curgdt.address = (unsigned long)newgdt; - - __asm__ __volatile__ ( - "lgdtq %0\n" - : : "m" (curgdt) - ); -}; - -static void load_segments(void) -{ - __asm__ __volatile__ ( - "\tmovl %0,%%ds\n" - "\tmovl %0,%%es\n" - "\tmovl %0,%%ss\n" - "\tmovl %0,%%fs\n" - "\tmovl %0,%%gs\n" - : : "a" (__KERNEL_DS) : "memory" - ); -} - int machine_kexec_prepare(struct kimage *image) { unsigned long start_pgtable; @@ -209,23 +168,6 @@ NORET_TYPE void machine_kexec(struct kim page_list[PA_TABLE_PAGE] = (unsigned long)__pa(page_address(image->control_code_page)); - /* The segment registers are funny things, they have both a - * visible and an invisible part. Whenever the visible part is - * set to a specific selector, the invisible part is loaded - * with from a table in memory. At no other time is the - * descriptor table in memory accessed. - * - * I take advantage of this here by force loading the - * segments, before I zap the gdt with an invalid value. - */ - load_segments(); - /* The gdt & idt are now invalid. - * If you want to load them you must set up your own idt & gdt. - */ - set_gdt(phys_to_virt(0),0); - set_idt(phys_to_virt(0),0); - - /* now call it */ relocate_kernel((unsigned long)image->head, (unsigned long)page_list, image->start); } diff -r 1c0aeb8749d2 -r 405dae994591 arch/x86_64/kernel/relocate_kernel.S --- a/arch/x86_64/kernel/relocate_kernel.S Mon Jun 04 10:05:23 2007 +0100 +++ b/arch/x86_64/kernel/relocate_kernel.S Mon Jun 04 10:05:23 2007 +0100 @@ -159,13 +159,39 @@ relocate_new_kernel: movq PTR(PA_PGD)(%rsi), %r9 movq %r9, %cr3 + /* setup idt */ + movq %r8, %rax + addq $(idt_80 - relocate_kernel), %rax + lidtq (%rax) + + /* setup gdt */ + movq %r8, %rax + addq $(gdt - relocate_kernel), %rax + movq %r8, %r9 + addq $((gdt_80 - relocate_kernel) + 2), %r9 + movq %rax, (%r9) + + movq %r8, %rax + addq $(gdt_80 - relocate_kernel), %rax + lgdtq (%rax) + + /* setup data segment registers */ + xorl %eax, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %fs + movl %eax, %gs + movl %eax, %ss + /* setup a new stack at the end of the physical control page */ lea 4096(%r8), %rsp - /* jump to identity mapped page */ - addq $(identity_mapped - relocate_kernel), %r8 - pushq %r8 - ret + /* load new code segment and jump to identity mapped page */ + movq %r8, %rax + addq $(identity_mapped - relocate_kernel), %rax + pushq $(gdt_cs - gdt) + pushq %rax + lretq identity_mapped: /* store the start address on the stack */ @@ -272,5 +298,19 @@ 3: xorq %r13, %r13 xorq %r14, %r14 xorq %r15, %r15 - ret + + .align 16 +gdt: + .quad 0x0000000000000000 /* NULL descriptor */ +gdt_cs: + .quad 0x00af9a000000ffff +gdt_end: + +gdt_80: + .word gdt_end - gdt - 1 /* limit */ + .quad 0 /* base - filled in by code above */ + +idt_80: + .word 0 /* limit */ + .quad 0 /* base */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |