ia64/xen-unstable

view patches/linux-2.6.18/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch @ 14131:64d80037e524

Save elfnotes in VM sxpr under image/notes, and load them on restore.
Signed-off-by: Brendan Cully <brendan@cs.ubc.ca>
author kfraser@localhost.localdomain
date Mon Feb 26 09:59:56 2007 +0000 (2007-02-26)
parents 3adf00179a63
children
line source
1 diff -pruN ../orig-linux-2.6.18/arch/i386/kernel/machine_kexec.c ./arch/i386/kernel/machine_kexec.c
2 --- ../orig-linux-2.6.18/arch/i386/kernel/machine_kexec.c 2006-09-20 04:42:06.000000000 +0100
3 +++ ./arch/i386/kernel/machine_kexec.c 2007-01-12 16:03:23.000000000 +0000
4 @@ -20,70 +20,13 @@
5 #include <asm/system.h>
7 #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
8 -
9 -#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
10 -#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
11 -#define L2_ATTR (_PAGE_PRESENT)
12 -
13 -#define LEVEL0_SIZE (1UL << 12UL)
14 -
15 -#ifndef CONFIG_X86_PAE
16 -#define LEVEL1_SIZE (1UL << 22UL)
17 -static u32 pgtable_level1[1024] PAGE_ALIGNED;
18 -
19 -static void identity_map_page(unsigned long address)
20 -{
21 - unsigned long level1_index, level2_index;
22 - u32 *pgtable_level2;
23 -
24 - /* Find the current page table */
25 - pgtable_level2 = __va(read_cr3());
26 -
27 - /* Find the indexes of the physical address to identity map */
28 - level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
29 - level2_index = address / LEVEL1_SIZE;
30 -
31 - /* Identity map the page table entry */
32 - pgtable_level1[level1_index] = address | L0_ATTR;
33 - pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
34 -
35 - /* Flush the tlb so the new mapping takes effect.
36 - * Global tlb entries are not flushed but that is not an issue.
37 - */
38 - load_cr3(pgtable_level2);
39 -}
40 -
41 -#else
42 -#define LEVEL1_SIZE (1UL << 21UL)
43 -#define LEVEL2_SIZE (1UL << 30UL)
44 -static u64 pgtable_level1[512] PAGE_ALIGNED;
45 -static u64 pgtable_level2[512] PAGE_ALIGNED;
46 -
47 -static void identity_map_page(unsigned long address)
48 -{
49 - unsigned long level1_index, level2_index, level3_index;
50 - u64 *pgtable_level3;
51 -
52 - /* Find the current page table */
53 - pgtable_level3 = __va(read_cr3());
54 -
55 - /* Find the indexes of the physical address to identity map */
56 - level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
57 - level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
58 - level3_index = address / LEVEL2_SIZE;
59 -
60 - /* Identity map the page table entry */
61 - pgtable_level1[level1_index] = address | L0_ATTR;
62 - pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
63 - set_64bit(&pgtable_level3[level3_index],
64 - __pa(pgtable_level2) | L2_ATTR);
65 -
66 - /* Flush the tlb so the new mapping takes effect.
67 - * Global tlb entries are not flushed but that is not an issue.
68 - */
69 - load_cr3(pgtable_level3);
70 -}
71 +static u32 kexec_pgd[1024] PAGE_ALIGNED;
72 +#ifdef CONFIG_X86_PAE
73 +static u32 kexec_pmd0[1024] PAGE_ALIGNED;
74 +static u32 kexec_pmd1[1024] PAGE_ALIGNED;
75 #endif
76 +static u32 kexec_pte0[1024] PAGE_ALIGNED;
77 +static u32 kexec_pte1[1024] PAGE_ALIGNED;
79 static void set_idt(void *newidt, __u16 limit)
80 {
81 @@ -127,16 +70,6 @@ static void load_segments(void)
82 #undef __STR
83 }
85 -typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
86 - unsigned long indirection_page,
87 - unsigned long reboot_code_buffer,
88 - unsigned long start_address,
89 - unsigned int has_pae) ATTRIB_NORET;
90 -
91 -extern const unsigned char relocate_new_kernel[];
92 -extern void relocate_new_kernel_end(void);
93 -extern const unsigned int relocate_new_kernel_size;
94 -
95 /*
96 * A architecture hook called to validate the
97 * proposed image and prepare the control pages
98 @@ -169,25 +102,29 @@ void machine_kexec_cleanup(struct kimage
99 */
100 NORET_TYPE void machine_kexec(struct kimage *image)
101 {
102 - unsigned long page_list;
103 - unsigned long reboot_code_buffer;
104 -
105 - relocate_new_kernel_t rnk;
106 + unsigned long page_list[PAGES_NR];
107 + void *control_page;
109 /* Interrupts aren't acceptable while we reboot */
110 local_irq_disable();
112 - /* Compute some offsets */
113 - reboot_code_buffer = page_to_pfn(image->control_code_page)
114 - << PAGE_SHIFT;
115 - page_list = image->head;
116 -
117 - /* Set up an identity mapping for the reboot_code_buffer */
118 - identity_map_page(reboot_code_buffer);
119 -
120 - /* copy it out */
121 - memcpy((void *)reboot_code_buffer, relocate_new_kernel,
122 - relocate_new_kernel_size);
123 + control_page = page_address(image->control_code_page);
124 + memcpy(control_page, relocate_kernel, PAGE_SIZE);
125 +
126 + page_list[PA_CONTROL_PAGE] = __pa(control_page);
127 + page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
128 + page_list[PA_PGD] = __pa(kexec_pgd);
129 + page_list[VA_PGD] = (unsigned long)kexec_pgd;
130 +#ifdef CONFIG_X86_PAE
131 + page_list[PA_PMD_0] = __pa(kexec_pmd0);
132 + page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
133 + page_list[PA_PMD_1] = __pa(kexec_pmd1);
134 + page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
135 +#endif
136 + page_list[PA_PTE_0] = __pa(kexec_pte0);
137 + page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
138 + page_list[PA_PTE_1] = __pa(kexec_pte1);
139 + page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
141 /* The segment registers are funny things, they have both a
142 * visible and an invisible part. Whenever the visible part is
143 @@ -206,6 +143,6 @@ NORET_TYPE void machine_kexec(struct kim
144 set_idt(phys_to_virt(0),0);
146 /* now call it */
147 - rnk = (relocate_new_kernel_t) reboot_code_buffer;
148 - (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
149 + relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
150 + image->start, cpu_has_pae);
151 }
152 diff -pruN ../orig-linux-2.6.18/arch/i386/kernel/relocate_kernel.S ./arch/i386/kernel/relocate_kernel.S
153 --- ../orig-linux-2.6.18/arch/i386/kernel/relocate_kernel.S 2006-09-20 04:42:06.000000000 +0100
154 +++ ./arch/i386/kernel/relocate_kernel.S 2007-01-12 16:03:23.000000000 +0000
155 @@ -7,16 +7,138 @@
156 */
158 #include <linux/linkage.h>
159 +#include <asm/page.h>
160 +#include <asm/kexec.h>
161 +
162 +/*
163 + * Must be relocatable PIC code callable as a C function
164 + */
165 +
166 +#define PTR(x) (x << 2)
167 +#define PAGE_ALIGNED (1 << PAGE_SHIFT)
168 +#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
169 +#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */
170 +
171 + .text
172 + .align PAGE_ALIGNED
173 + .globl relocate_kernel
174 +relocate_kernel:
175 + movl 8(%esp), %ebp /* list of pages */
176 +
177 +#ifdef CONFIG_X86_PAE
178 + /* map the control page at its virtual address */
179 +
180 + movl PTR(VA_PGD)(%ebp), %edi
181 + movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
182 + andl $0xc0000000, %eax
183 + shrl $27, %eax
184 + addl %edi, %eax
185 +
186 + movl PTR(PA_PMD_0)(%ebp), %edx
187 + orl $PAE_PGD_ATTR, %edx
188 + movl %edx, (%eax)
189 +
190 + movl PTR(VA_PMD_0)(%ebp), %edi
191 + movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
192 + andl $0x3fe00000, %eax
193 + shrl $18, %eax
194 + addl %edi, %eax
195 +
196 + movl PTR(PA_PTE_0)(%ebp), %edx
197 + orl $PAGE_ATTR, %edx
198 + movl %edx, (%eax)
199 +
200 + movl PTR(VA_PTE_0)(%ebp), %edi
201 + movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
202 + andl $0x001ff000, %eax
203 + shrl $9, %eax
204 + addl %edi, %eax
205 +
206 + movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
207 + orl $PAGE_ATTR, %edx
208 + movl %edx, (%eax)
209 +
210 + /* identity map the control page at its physical address */
211 +
212 + movl PTR(VA_PGD)(%ebp), %edi
213 + movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
214 + andl $0xc0000000, %eax
215 + shrl $27, %eax
216 + addl %edi, %eax
217 +
218 + movl PTR(PA_PMD_1)(%ebp), %edx
219 + orl $PAE_PGD_ATTR, %edx
220 + movl %edx, (%eax)
221 +
222 + movl PTR(VA_PMD_1)(%ebp), %edi
223 + movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
224 + andl $0x3fe00000, %eax
225 + shrl $18, %eax
226 + addl %edi, %eax
227 +
228 + movl PTR(PA_PTE_1)(%ebp), %edx
229 + orl $PAGE_ATTR, %edx
230 + movl %edx, (%eax)
231 +
232 + movl PTR(VA_PTE_1)(%ebp), %edi
233 + movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
234 + andl $0x001ff000, %eax
235 + shrl $9, %eax
236 + addl %edi, %eax
237 +
238 + movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
239 + orl $PAGE_ATTR, %edx
240 + movl %edx, (%eax)
241 +#else
242 + /* map the control page at its virtual address */
243 +
244 + movl PTR(VA_PGD)(%ebp), %edi
245 + movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
246 + andl $0xffc00000, %eax
247 + shrl $20, %eax
248 + addl %edi, %eax
249 +
250 + movl PTR(PA_PTE_0)(%ebp), %edx
251 + orl $PAGE_ATTR, %edx
252 + movl %edx, (%eax)
253 +
254 + movl PTR(VA_PTE_0)(%ebp), %edi
255 + movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
256 + andl $0x003ff000, %eax
257 + shrl $10, %eax
258 + addl %edi, %eax
259 +
260 + movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
261 + orl $PAGE_ATTR, %edx
262 + movl %edx, (%eax)
263 +
264 + /* identity map the control page at its physical address */
265 +
266 + movl PTR(VA_PGD)(%ebp), %edi
267 + movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
268 + andl $0xffc00000, %eax
269 + shrl $20, %eax
270 + addl %edi, %eax
271 +
272 + movl PTR(PA_PTE_1)(%ebp), %edx
273 + orl $PAGE_ATTR, %edx
274 + movl %edx, (%eax)
275 +
276 + movl PTR(VA_PTE_1)(%ebp), %edi
277 + movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
278 + andl $0x003ff000, %eax
279 + shrl $10, %eax
280 + addl %edi, %eax
281 +
282 + movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
283 + orl $PAGE_ATTR, %edx
284 + movl %edx, (%eax)
285 +#endif
287 - /*
288 - * Must be relocatable PIC code callable as a C function, that once
289 - * it starts can not use the previous processes stack.
290 - */
291 - .globl relocate_new_kernel
292 relocate_new_kernel:
293 /* read the arguments and say goodbye to the stack */
294 movl 4(%esp), %ebx /* page_list */
295 - movl 8(%esp), %ebp /* reboot_code_buffer */
296 + movl 8(%esp), %ebp /* list of pages */
297 movl 12(%esp), %edx /* start address */
298 movl 16(%esp), %ecx /* cpu_has_pae */
300 @@ -24,11 +146,26 @@ relocate_new_kernel:
301 pushl $0
302 popfl
304 - /* set a new stack at the bottom of our page... */
305 - lea 4096(%ebp), %esp
306 + /* get physical address of control page now */
307 + /* this is impossible after page table switch */
308 + movl PTR(PA_CONTROL_PAGE)(%ebp), %edi
309 +
310 + /* switch to new set of page tables */
311 + movl PTR(PA_PGD)(%ebp), %eax
312 + movl %eax, %cr3
313 +
314 + /* setup a new stack at the end of the physical control page */
315 + lea 4096(%edi), %esp
317 - /* store the parameters back on the stack */
318 - pushl %edx /* store the start address */
319 + /* jump to identity mapped page */
320 + movl %edi, %eax
321 + addl $(identity_mapped - relocate_kernel), %eax
322 + pushl %eax
323 + ret
324 +
325 +identity_mapped:
326 + /* store the start address on the stack */
327 + pushl %edx
329 /* Set cr0 to a known state:
330 * 31 0 == Paging disabled
331 @@ -113,8 +250,3 @@ relocate_new_kernel:
332 xorl %edi, %edi
333 xorl %ebp, %ebp
334 ret
335 -relocate_new_kernel_end:
336 -
337 - .globl relocate_new_kernel_size
338 -relocate_new_kernel_size:
339 - .long relocate_new_kernel_end - relocate_new_kernel
340 diff -pruN ../orig-linux-2.6.18/include/asm-i386/kexec.h ./include/asm-i386/kexec.h
341 --- ../orig-linux-2.6.18/include/asm-i386/kexec.h 2006-09-20 04:42:06.000000000 +0100
342 +++ ./include/asm-i386/kexec.h 2007-01-12 16:03:23.000000000 +0000
343 @@ -1,6 +1,26 @@
344 #ifndef _I386_KEXEC_H
345 #define _I386_KEXEC_H
347 +#define PA_CONTROL_PAGE 0
348 +#define VA_CONTROL_PAGE 1
349 +#define PA_PGD 2
350 +#define VA_PGD 3
351 +#define PA_PTE_0 4
352 +#define VA_PTE_0 5
353 +#define PA_PTE_1 6
354 +#define VA_PTE_1 7
355 +#ifdef CONFIG_X86_PAE
356 +#define PA_PMD_0 8
357 +#define VA_PMD_0 9
358 +#define PA_PMD_1 10
359 +#define VA_PMD_1 11
360 +#define PAGES_NR 12
361 +#else
362 +#define PAGES_NR 8
363 +#endif
364 +
365 +#ifndef __ASSEMBLY__
366 +
367 #include <asm/fixmap.h>
368 #include <asm/ptrace.h>
369 #include <asm/string.h>
370 @@ -72,5 +92,12 @@ static inline void crash_setup_regs(stru
371 newregs->eip = (unsigned long)current_text_addr();
372 }
373 }
374 +asmlinkage NORET_TYPE void
375 +relocate_kernel(unsigned long indirection_page,
376 + unsigned long control_page,
377 + unsigned long start_address,
378 + unsigned int has_pae) ATTRIB_NORET;
379 +
380 +#endif /* __ASSEMBLY__ */
382 #endif /* _I386_KEXEC_H */