1 Subject: kexec: Move asm segment handling code to the assembly file (i386)
2 From: http://xenbits.xensource.com/xen-unstable.hg (tip 13816)
3 Patch-mainline: obsolete
5 This patch moves the idt, gdt, and segment handling code from machine_kexec.c
6 to relocate_kernel.S. The main reason behind this move is to avoid code
7 duplication in the Xen hypervisor. With this patch all code required to kexec
8 is put on the control page.
10 On top of that this patch also counts as a cleanup - I think it is much
11 nicer to write assembly directly in assembly files than wrap inline assembly
12 in C functions for no apparent reason.
14 Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
15 Acked-by: jbeulich@novell.com
18 Applies to 2.6.19-rc1.
20 machine_kexec.c | 59 -----------------------------------------------------
21 relocate_kernel.S | 58 +++++++++++++++++++++++++++++++++++++++++++++++-----
22 2 files changed, 53 insertions(+), 64 deletions(-)
24 Index: head-2008-11-17/arch/x86/kernel/machine_kexec_32.c
25 ===================================================================
26 --- head-2008-11-17.orig/arch/x86/kernel/machine_kexec_32.c 2008-11-17 13:15:56.000000000 +0100
27 +++ head-2008-11-17/arch/x86/kernel/machine_kexec_32.c 2008-11-17 13:38:03.000000000 +0100
28 @@ -34,48 +34,6 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
29 static u32 kexec_pte0[1024] PAGE_ALIGNED;
30 static u32 kexec_pte1[1024] PAGE_ALIGNED;
32 -static void set_idt(void *newidt, __u16 limit)
34 - struct desc_ptr curidt;
36 - /* ia32 supports unaliged loads & stores */
37 - curidt.size = limit;
38 - curidt.address = (unsigned long)newidt;
44 -static void set_gdt(void *newgdt, __u16 limit)
46 - struct desc_ptr curgdt;
48 - /* ia32 supports unaligned loads & stores */
49 - curgdt.size = limit;
50 - curgdt.address = (unsigned long)newgdt;
55 -static void load_segments(void)
58 -#define STR(X) __STR(X)
60 - __asm__ __volatile__ (
61 - "\tljmp $"STR(__KERNEL_CS)",$1f\n"
63 - "\tmovl $"STR(__KERNEL_DS)",%%eax\n"
64 - "\tmovl %%eax,%%ds\n"
65 - "\tmovl %%eax,%%es\n"
66 - "\tmovl %%eax,%%fs\n"
67 - "\tmovl %%eax,%%gs\n"
68 - "\tmovl %%eax,%%ss\n"
69 - ::: "eax", "memory");
75 * A architecture hook called to validate the
76 * proposed image and prepare the control pages
77 @@ -167,23 +125,6 @@ void machine_kexec(struct kimage *image)
78 page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page)
81 - /* The segment registers are funny things, they have both a
82 - * visible and an invisible part. Whenever the visible part is
83 - * set to a specific selector, the invisible part is loaded
84 - * with from a table in memory. At no other time is the
85 - * descriptor table in memory accessed.
87 - * I take advantage of this here by force loading the
88 - * segments, before I zap the gdt with an invalid value.
91 - /* The gdt & idt are now invalid.
92 - * If you want to load them you must set up your own idt & gdt.
94 - set_gdt(phys_to_virt(0),0);
95 - set_idt(phys_to_virt(0),0);
98 image->start = relocate_kernel_ptr((unsigned long)image->head,
99 (unsigned long)page_list,
100 image->start, cpu_has_pae,
101 Index: head-2008-11-17/arch/x86/kernel/relocate_kernel_32.S
102 ===================================================================
103 --- head-2008-11-17.orig/arch/x86/kernel/relocate_kernel_32.S 2008-11-17 13:15:56.000000000 +0100
104 +++ head-2008-11-17/arch/x86/kernel/relocate_kernel_32.S 2008-11-17 13:38:03.000000000 +0100
105 @@ -199,14 +199,45 @@ relocate_new_kernel:
106 movl PTR(PA_PGD)(%ebp), %eax
111 + addl $(idt_48 - relocate_kernel), %eax
116 + addl $(gdt - relocate_kernel), %eax
118 + addl $((gdt_48 - relocate_kernel) + 2), %esi
122 + addl $(gdt_48 - relocate_kernel), %eax
125 + /* setup data segment registers */
126 + mov $(gdt_ds - gdt), %eax
133 /* setup a new stack at the end of the physical control page */
134 lea PAGE_SIZE(%edi), %esp
136 - /* jump to identity mapped page */
138 - addl $(identity_mapped - relocate_kernel), %eax
141 + /* load new code segment and jump to identity mapped page */
147 + movl $(gdt_cs - gdt), %eax
150 + addl $(identity_mapped - relocate_kernel),%eax
155 /* store the start address on the stack */
156 @@ -378,5 +409,22 @@ swap_pages:
162 + .quad 0x0000000000000000 /* NULL descriptor */
164 + .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
166 + .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
170 + .word gdt_end - gdt - 1 /* limit */
171 + .long 0 /* base - filled in by code above */
174 + .word 0 /* limit */
177 .globl kexec_control_code_size
178 .set kexec_control_code_size, . - relocate_kernel