ia64/xen-unstable

view patches/linux-2.6.18/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.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/x86_64/kernel/machine_kexec.c ./arch/x86_64/kernel/machine_kexec.c
2 --- ../orig-linux-2.6.18/arch/x86_64/kernel/machine_kexec.c 2006-09-20 04:42:06.000000000 +0100
3 +++ ./arch/x86_64/kernel/machine_kexec.c 2007-01-12 16:03:49.000000000 +0000
4 @@ -15,6 +15,15 @@
5 #include <asm/mmu_context.h>
6 #include <asm/io.h>
8 +#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
9 +static u64 kexec_pgd[512] PAGE_ALIGNED;
10 +static u64 kexec_pud0[512] PAGE_ALIGNED;
11 +static u64 kexec_pmd0[512] PAGE_ALIGNED;
12 +static u64 kexec_pte0[512] PAGE_ALIGNED;
13 +static u64 kexec_pud1[512] PAGE_ALIGNED;
14 +static u64 kexec_pmd1[512] PAGE_ALIGNED;
15 +static u64 kexec_pte1[512] PAGE_ALIGNED;
16 +
17 static void init_level2_page(pmd_t *level2p, unsigned long addr)
18 {
19 unsigned long end_addr;
20 @@ -144,32 +153,19 @@ static void load_segments(void)
21 );
22 }
24 -typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page,
25 - unsigned long control_code_buffer,
26 - unsigned long start_address,
27 - unsigned long pgtable) ATTRIB_NORET;
28 -
29 -extern const unsigned char relocate_new_kernel[];
30 -extern const unsigned long relocate_new_kernel_size;
31 -
32 int machine_kexec_prepare(struct kimage *image)
33 {
34 - unsigned long start_pgtable, control_code_buffer;
35 + unsigned long start_pgtable;
36 int result;
38 /* Calculate the offsets */
39 start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
40 - control_code_buffer = start_pgtable + PAGE_SIZE;
42 /* Setup the identity mapped 64bit page table */
43 result = init_pgtable(image, start_pgtable);
44 if (result)
45 return result;
47 - /* Place the code in the reboot code buffer */
48 - memcpy(__va(control_code_buffer), relocate_new_kernel,
49 - relocate_new_kernel_size);
50 -
51 return 0;
52 }
54 @@ -184,28 +180,34 @@ void machine_kexec_cleanup(struct kimage
55 */
56 NORET_TYPE void machine_kexec(struct kimage *image)
57 {
58 - unsigned long page_list;
59 - unsigned long control_code_buffer;
60 - unsigned long start_pgtable;
61 - relocate_new_kernel_t rnk;
62 + unsigned long page_list[PAGES_NR];
63 + void *control_page;
65 /* Interrupts aren't acceptable while we reboot */
66 local_irq_disable();
68 - /* Calculate the offsets */
69 - page_list = image->head;
70 - start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
71 - control_code_buffer = start_pgtable + PAGE_SIZE;
72 + control_page = page_address(image->control_code_page) + PAGE_SIZE;
73 + memcpy(control_page, relocate_kernel, PAGE_SIZE);
75 - /* Set the low half of the page table to my identity mapped
76 - * page table for kexec. Leave the high half pointing at the
77 - * kernel pages. Don't bother to flush the global pages
78 - * as that will happen when I fully switch to my identity mapped
79 - * page table anyway.
80 - */
81 - memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2);
82 - __flush_tlb();
83 + page_list[PA_CONTROL_PAGE] = __pa(control_page);
84 + page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
85 + page_list[PA_PGD] = __pa(kexec_pgd);
86 + page_list[VA_PGD] = (unsigned long)kexec_pgd;
87 + page_list[PA_PUD_0] = __pa(kexec_pud0);
88 + page_list[VA_PUD_0] = (unsigned long)kexec_pud0;
89 + page_list[PA_PMD_0] = __pa(kexec_pmd0);
90 + page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
91 + page_list[PA_PTE_0] = __pa(kexec_pte0);
92 + page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
93 + page_list[PA_PUD_1] = __pa(kexec_pud1);
94 + page_list[VA_PUD_1] = (unsigned long)kexec_pud1;
95 + page_list[PA_PMD_1] = __pa(kexec_pmd1);
96 + page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
97 + page_list[PA_PTE_1] = __pa(kexec_pte1);
98 + page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
100 + page_list[PA_TABLE_PAGE] =
101 + (unsigned long)__pa(page_address(image->control_code_page));
103 /* The segment registers are funny things, they have both a
104 * visible and an invisible part. Whenever the visible part is
105 @@ -222,7 +224,8 @@ NORET_TYPE void machine_kexec(struct kim
106 */
107 set_gdt(phys_to_virt(0),0);
108 set_idt(phys_to_virt(0),0);
109 +
110 /* now call it */
111 - rnk = (relocate_new_kernel_t) control_code_buffer;
112 - (*rnk)(page_list, control_code_buffer, image->start, start_pgtable);
113 + relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
114 + image->start);
115 }
116 diff -pruN ../orig-linux-2.6.18/arch/x86_64/kernel/relocate_kernel.S ./arch/x86_64/kernel/relocate_kernel.S
117 --- ../orig-linux-2.6.18/arch/x86_64/kernel/relocate_kernel.S 2006-09-20 04:42:06.000000000 +0100
118 +++ ./arch/x86_64/kernel/relocate_kernel.S 2007-01-12 16:03:49.000000000 +0000
119 @@ -7,31 +7,169 @@
120 */
122 #include <linux/linkage.h>
123 +#include <asm/page.h>
124 +#include <asm/kexec.h>
126 - /*
127 - * Must be relocatable PIC code callable as a C function, that once
128 - * it starts can not use the previous processes stack.
129 - */
130 - .globl relocate_new_kernel
131 +/*
132 + * Must be relocatable PIC code callable as a C function
133 + */
134 +
135 +#define PTR(x) (x << 3)
136 +#define PAGE_ALIGNED (1 << PAGE_SHIFT)
137 +#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
138 +
139 + .text
140 + .align PAGE_ALIGNED
141 .code64
142 + .globl relocate_kernel
143 +relocate_kernel:
144 + /* %rdi indirection_page
145 + * %rsi page_list
146 + * %rdx start address
147 + */
148 +
149 + /* map the control page at its virtual address */
150 +
151 + movq $0x0000ff8000000000, %r10 /* mask */
152 + mov $(39 - 3), %cl /* bits to shift */
153 + movq PTR(VA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
154 +
155 + movq %r11, %r9
156 + andq %r10, %r9
157 + shrq %cl, %r9
158 +
159 + movq PTR(VA_PGD)(%rsi), %r8
160 + addq %r8, %r9
161 + movq PTR(PA_PUD_0)(%rsi), %r8
162 + orq $PAGE_ATTR, %r8
163 + movq %r8, (%r9)
164 +
165 + shrq $9, %r10
166 + sub $9, %cl
167 +
168 + movq %r11, %r9
169 + andq %r10, %r9
170 + shrq %cl, %r9
171 +
172 + movq PTR(VA_PUD_0)(%rsi), %r8
173 + addq %r8, %r9
174 + movq PTR(PA_PMD_0)(%rsi), %r8
175 + orq $PAGE_ATTR, %r8
176 + movq %r8, (%r9)
177 +
178 + shrq $9, %r10
179 + sub $9, %cl
180 +
181 + movq %r11, %r9
182 + andq %r10, %r9
183 + shrq %cl, %r9
184 +
185 + movq PTR(VA_PMD_0)(%rsi), %r8
186 + addq %r8, %r9
187 + movq PTR(PA_PTE_0)(%rsi), %r8
188 + orq $PAGE_ATTR, %r8
189 + movq %r8, (%r9)
190 +
191 + shrq $9, %r10
192 + sub $9, %cl
193 +
194 + movq %r11, %r9
195 + andq %r10, %r9
196 + shrq %cl, %r9
197 +
198 + movq PTR(VA_PTE_0)(%rsi), %r8
199 + addq %r8, %r9
200 + movq PTR(PA_CONTROL_PAGE)(%rsi), %r8
201 + orq $PAGE_ATTR, %r8
202 + movq %r8, (%r9)
203 +
204 + /* identity map the control page at its physical address */
205 +
206 + movq $0x0000ff8000000000, %r10 /* mask */
207 + mov $(39 - 3), %cl /* bits to shift */
208 + movq PTR(PA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
209 +
210 + movq %r11, %r9
211 + andq %r10, %r9
212 + shrq %cl, %r9
213 +
214 + movq PTR(VA_PGD)(%rsi), %r8
215 + addq %r8, %r9
216 + movq PTR(PA_PUD_1)(%rsi), %r8
217 + orq $PAGE_ATTR, %r8
218 + movq %r8, (%r9)
219 +
220 + shrq $9, %r10
221 + sub $9, %cl
222 +
223 + movq %r11, %r9
224 + andq %r10, %r9
225 + shrq %cl, %r9
226 +
227 + movq PTR(VA_PUD_1)(%rsi), %r8
228 + addq %r8, %r9
229 + movq PTR(PA_PMD_1)(%rsi), %r8
230 + orq $PAGE_ATTR, %r8
231 + movq %r8, (%r9)
232 +
233 + shrq $9, %r10
234 + sub $9, %cl
235 +
236 + movq %r11, %r9
237 + andq %r10, %r9
238 + shrq %cl, %r9
239 +
240 + movq PTR(VA_PMD_1)(%rsi), %r8
241 + addq %r8, %r9
242 + movq PTR(PA_PTE_1)(%rsi), %r8
243 + orq $PAGE_ATTR, %r8
244 + movq %r8, (%r9)
245 +
246 + shrq $9, %r10
247 + sub $9, %cl
248 +
249 + movq %r11, %r9
250 + andq %r10, %r9
251 + shrq %cl, %r9
252 +
253 + movq PTR(VA_PTE_1)(%rsi), %r8
254 + addq %r8, %r9
255 + movq PTR(PA_CONTROL_PAGE)(%rsi), %r8
256 + orq $PAGE_ATTR, %r8
257 + movq %r8, (%r9)
258 +
259 relocate_new_kernel:
260 - /* %rdi page_list
261 - * %rsi reboot_code_buffer
262 + /* %rdi indirection_page
263 + * %rsi page_list
264 * %rdx start address
265 - * %rcx page_table
266 - * %r8 arg5
267 - * %r9 arg6
268 */
270 /* zero out flags, and disable interrupts */
271 pushq $0
272 popfq
274 - /* set a new stack at the bottom of our page... */
275 - lea 4096(%rsi), %rsp
276 + /* get physical address of control page now */
277 + /* this is impossible after page table switch */
278 + movq PTR(PA_CONTROL_PAGE)(%rsi), %r8
279 +
280 + /* get physical address of page table now too */
281 + movq PTR(PA_TABLE_PAGE)(%rsi), %rcx
282 +
283 + /* switch to new set of page tables */
284 + movq PTR(PA_PGD)(%rsi), %r9
285 + movq %r9, %cr3
286 +
287 + /* setup a new stack at the end of the physical control page */
288 + lea 4096(%r8), %rsp
289 +
290 + /* jump to identity mapped page */
291 + addq $(identity_mapped - relocate_kernel), %r8
292 + pushq %r8
293 + ret
295 - /* store the parameters back on the stack */
296 - pushq %rdx /* store the start address */
297 +identity_mapped:
298 + /* store the start address on the stack */
299 + pushq %rdx
301 /* Set cr0 to a known state:
302 * 31 1 == Paging enabled
303 @@ -136,8 +274,3 @@ relocate_new_kernel:
304 xorq %r15, %r15
306 ret
307 -relocate_new_kernel_end:
308 -
309 - .globl relocate_new_kernel_size
310 -relocate_new_kernel_size:
311 - .quad relocate_new_kernel_end - relocate_new_kernel
312 diff -pruN ../orig-linux-2.6.18/include/asm-x86_64/kexec.h ./include/asm-x86_64/kexec.h
313 --- ../orig-linux-2.6.18/include/asm-x86_64/kexec.h 2006-09-20 04:42:06.000000000 +0100
314 +++ ./include/asm-x86_64/kexec.h 2007-01-12 16:03:49.000000000 +0000
315 @@ -1,6 +1,27 @@
316 #ifndef _X86_64_KEXEC_H
317 #define _X86_64_KEXEC_H
319 +#define PA_CONTROL_PAGE 0
320 +#define VA_CONTROL_PAGE 1
321 +#define PA_PGD 2
322 +#define VA_PGD 3
323 +#define PA_PUD_0 4
324 +#define VA_PUD_0 5
325 +#define PA_PMD_0 6
326 +#define VA_PMD_0 7
327 +#define PA_PTE_0 8
328 +#define VA_PTE_0 9
329 +#define PA_PUD_1 10
330 +#define VA_PUD_1 11
331 +#define PA_PMD_1 12
332 +#define VA_PMD_1 13
333 +#define PA_PTE_1 14
334 +#define VA_PTE_1 15
335 +#define PA_TABLE_PAGE 16
336 +#define PAGES_NR 17
337 +
338 +#ifndef __ASSEMBLY__
339 +
340 #include <linux/string.h>
342 #include <asm/page.h>
343 @@ -64,4 +85,12 @@ static inline void crash_setup_regs(stru
344 newregs->rip = (unsigned long)current_text_addr();
345 }
346 }
347 +
348 +NORET_TYPE void
349 +relocate_kernel(unsigned long indirection_page,
350 + unsigned long page_list,
351 + unsigned long start_address) ATTRIB_NORET;
352 +
353 +#endif /* __ASSEMBLY__ */
354 +
355 #endif /* _X86_64_KEXEC_H */