]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.xen/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.xen / linux-2.6.19-rc1-kexec-move_segment_code-i386.patch
CommitLineData
cc90b958
BS
1Subject: kexec: Move asm segment handling code to the assembly file (i386)
2From: http://xenbits.xensource.com/xen-unstable.hg (tip 13816)
3Patch-mainline: obsolete
4
5This patch moves the idt, gdt, and segment handling code from machine_kexec.c
6to relocate_kernel.S. The main reason behind this move is to avoid code
7duplication in the Xen hypervisor. With this patch all code required to kexec
8is put on the control page.
9
10On top of that this patch also counts as a cleanup - I think it is much
11nicer to write assembly directly in assembly files than wrap inline assembly
12in C functions for no apparent reason.
13
14Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
15Acked-by: jbeulich@novell.com
16---
17
18 Applies to 2.6.19-rc1.
19
20 machine_kexec.c | 59 -----------------------------------------------------
21 relocate_kernel.S | 58 +++++++++++++++++++++++++++++++++++++++++++++++-----
22 2 files changed, 53 insertions(+), 64 deletions(-)
23
24Index: 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;
31
32-static void set_idt(void *newidt, __u16 limit)
33-{
34- struct desc_ptr curidt;
35-
36- /* ia32 supports unaliged loads & stores */
37- curidt.size = limit;
38- curidt.address = (unsigned long)newidt;
39-
40- load_idt(&curidt);
41-}
42-
43-
44-static void set_gdt(void *newgdt, __u16 limit)
45-{
46- struct desc_ptr curgdt;
47-
48- /* ia32 supports unaligned loads & stores */
49- curgdt.size = limit;
50- curgdt.address = (unsigned long)newgdt;
51-
52- load_gdt(&curgdt);
53-}
54-
55-static void load_segments(void)
56-{
57-#define __STR(X) #X
58-#define STR(X) __STR(X)
59-
60- __asm__ __volatile__ (
61- "\tljmp $"STR(__KERNEL_CS)",$1f\n"
62- "\t1:\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");
70-#undef STR
71-#undef __STR
72-}
73-
74 /*
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)
79 << PAGE_SHIFT);
80
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.
86- *
87- * I take advantage of this here by force loading the
88- * segments, before I zap the gdt with an invalid value.
89- */
90- load_segments();
91- /* The gdt & idt are now invalid.
92- * If you want to load them you must set up your own idt & gdt.
93- */
94- set_gdt(phys_to_virt(0),0);
95- set_idt(phys_to_virt(0),0);
96-
97- /* now call it */
98 image->start = relocate_kernel_ptr((unsigned long)image->head,
99 (unsigned long)page_list,
100 image->start, cpu_has_pae,
101Index: 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
107 movl %eax, %cr3
108
109+ /* setup idt */
110+ movl %edi, %eax
111+ addl $(idt_48 - relocate_kernel), %eax
112+ lidtl (%eax)
113+
114+ /* setup gdt */
115+ movl %edi, %eax
116+ addl $(gdt - relocate_kernel), %eax
117+ movl %edi, %esi
118+ addl $((gdt_48 - relocate_kernel) + 2), %esi
119+ movl %eax, (%esi)
120+
121+ movl %edi, %eax
122+ addl $(gdt_48 - relocate_kernel), %eax
123+ lgdtl (%eax)
124+
125+ /* setup data segment registers */
126+ mov $(gdt_ds - gdt), %eax
127+ mov %eax, %ds
128+ mov %eax, %es
129+ mov %eax, %fs
130+ mov %eax, %gs
131+ mov %eax, %ss
132+
133 /* setup a new stack at the end of the physical control page */
134 lea PAGE_SIZE(%edi), %esp
135
136- /* jump to identity mapped page */
137- movl %edi, %eax
138- addl $(identity_mapped - relocate_kernel), %eax
139- pushl %eax
140- ret
141+ /* load new code segment and jump to identity mapped page */
142+ movl %edi, %esi
143+ xorl %eax, %eax
144+ pushl %eax
145+ pushl %esi
146+ pushl %eax
147+ movl $(gdt_cs - gdt), %eax
148+ pushl %eax
149+ movl %edi, %eax
150+ addl $(identity_mapped - relocate_kernel),%eax
151+ pushl %eax
152+ iretl
153
154 identity_mapped:
155 /* store the start address on the stack */
156@@ -378,5 +409,22 @@ swap_pages:
157 popl %ebp
158 ret
159
160+ .align 16
161+gdt:
162+ .quad 0x0000000000000000 /* NULL descriptor */
163+gdt_cs:
164+ .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
165+gdt_ds:
166+ .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
167+gdt_end:
168+
169+gdt_48:
170+ .word gdt_end - gdt - 1 /* limit */
171+ .long 0 /* base - filled in by code above */
172+
173+idt_48:
174+ .word 0 /* limit */
175+ .long 0 /* base */
176+
177 .globl kexec_control_code_size
178 .set kexec_control_code_size, . - relocate_kernel