]>
Commit | Line | Data |
---|---|---|
6a930a95 BS |
1 | Subject: xen3 arch-i386 |
2 | From: http://xenbits.xensource.com/linux-2.6.18-xen.hg (tip 728:832aac894efd) | |
3 | Patch-mainline: obsolete | |
4 | Acked-by: jbeulich@novell.com | |
5 | ||
6 | Index: head-2008-11-25/arch/x86/kernel/asm-offsets_32.c | |
7 | =================================================================== | |
8 | --- head-2008-11-25.orig/arch/x86/kernel/asm-offsets_32.c 2008-11-25 12:33:06.000000000 +0100 | |
9 | +++ head-2008-11-25/arch/x86/kernel/asm-offsets_32.c 2008-11-25 12:35:53.000000000 +0100 | |
10 | @@ -91,9 +91,14 @@ void foo(void) | |
11 | OFFSET(pbe_orig_address, pbe, orig_address); | |
12 | OFFSET(pbe_next, pbe, next); | |
13 | ||
14 | +#ifndef CONFIG_X86_NO_TSS | |
15 | /* Offset from the sysenter stack to tss.sp0 */ | |
16 | - DEFINE(TSS_sysenter_sp0, offsetof(struct tss_struct, x86_tss.sp0) - | |
17 | + DEFINE(SYSENTER_stack_sp0, offsetof(struct tss_struct, x86_tss.sp0) - | |
18 | sizeof(struct tss_struct)); | |
19 | +#else | |
20 | + /* sysenter stack points directly to sp0 */ | |
21 | + DEFINE(SYSENTER_stack_sp0, 0); | |
22 | +#endif | |
23 | ||
24 | DEFINE(PAGE_SIZE_asm, PAGE_SIZE); | |
25 | DEFINE(PAGE_SHIFT_asm, PAGE_SHIFT); | |
26 | Index: head-2008-11-25/arch/x86/kernel/entry_32.S | |
27 | =================================================================== | |
28 | --- head-2008-11-25.orig/arch/x86/kernel/entry_32.S 2008-11-25 12:33:06.000000000 +0100 | |
29 | +++ head-2008-11-25/arch/x86/kernel/entry_32.S 2008-11-25 12:35:53.000000000 +0100 | |
30 | @@ -293,7 +293,7 @@ ENTRY(ia32_sysenter_target) | |
31 | CFI_SIGNAL_FRAME | |
32 | CFI_DEF_CFA esp, 0 | |
33 | CFI_REGISTER esp, ebp | |
34 | - movl TSS_sysenter_sp0(%esp),%esp | |
35 | + movl SYSENTER_stack_sp0(%esp),%esp | |
36 | sysenter_past_esp: | |
37 | /* | |
38 | * Interrupts are disabled here, but we can't trace it until | |
39 | @@ -782,7 +782,7 @@ END(device_not_available) | |
40 | * that sets up the real kernel stack. Check here, since we can't | |
41 | * allow the wrong stack to be used. | |
42 | * | |
43 | - * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have | |
44 | + * "SYSENTER_stack_sp0+12" is because the NMI/debug handler will have | |
45 | * already pushed 3 words if it hits on the sysenter instruction: | |
46 | * eflags, cs and eip. | |
47 | * | |
48 | @@ -794,7 +794,7 @@ END(device_not_available) | |
49 | cmpw $__KERNEL_CS,4(%esp); \ | |
50 | jne ok; \ | |
51 | label: \ | |
52 | - movl TSS_sysenter_sp0+offset(%esp),%esp; \ | |
53 | + movl SYSENTER_stack_sp0+offset(%esp),%esp; \ | |
54 | CFI_DEF_CFA esp, 0; \ | |
55 | CFI_UNDEFINED eip; \ | |
56 | pushfl; \ | |
57 | Index: head-2008-11-25/arch/x86/kernel/machine_kexec_32.c | |
58 | =================================================================== | |
59 | --- head-2008-11-25.orig/arch/x86/kernel/machine_kexec_32.c 2008-11-17 13:38:03.000000000 +0100 | |
60 | +++ head-2008-11-25/arch/x86/kernel/machine_kexec_32.c 2008-11-25 12:35:53.000000000 +0100 | |
61 | @@ -25,6 +25,10 @@ | |
62 | #include <asm/system.h> | |
63 | #include <asm/cacheflush.h> | |
64 | ||
65 | +#ifdef CONFIG_XEN | |
66 | +#include <xen/interface/kexec.h> | |
67 | +#endif | |
68 | + | |
69 | #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) | |
70 | static u32 kexec_pgd[1024] PAGE_ALIGNED; | |
71 | #ifdef CONFIG_X86_PAE | |
72 | @@ -34,6 +38,55 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED | |
73 | static u32 kexec_pte0[1024] PAGE_ALIGNED; | |
74 | static u32 kexec_pte1[1024] PAGE_ALIGNED; | |
75 | ||
76 | +#ifdef CONFIG_XEN | |
77 | + | |
78 | +#define __ma(x) (pfn_to_mfn(__pa((x)) >> PAGE_SHIFT) << PAGE_SHIFT) | |
79 | + | |
80 | +#if PAGES_NR > KEXEC_XEN_NO_PAGES | |
81 | +#error PAGES_NR is greater than KEXEC_XEN_NO_PAGES - Xen support will break | |
82 | +#endif | |
83 | + | |
84 | +#if PA_CONTROL_PAGE != 0 | |
85 | +#error PA_CONTROL_PAGE is non zero - Xen support will break | |
86 | +#endif | |
87 | + | |
88 | +void machine_kexec_setup_load_arg(xen_kexec_image_t *xki, struct kimage *image) | |
89 | +{ | |
90 | + void *control_page; | |
91 | + | |
92 | + memset(xki->page_list, 0, sizeof(xki->page_list)); | |
93 | + | |
94 | + control_page = page_address(image->control_code_page); | |
95 | + memcpy(control_page, relocate_kernel, PAGE_SIZE); | |
96 | + | |
97 | + xki->page_list[PA_CONTROL_PAGE] = __ma(control_page); | |
98 | + xki->page_list[PA_PGD] = __ma(kexec_pgd); | |
99 | +#ifdef CONFIG_X86_PAE | |
100 | + xki->page_list[PA_PMD_0] = __ma(kexec_pmd0); | |
101 | + xki->page_list[PA_PMD_1] = __ma(kexec_pmd1); | |
102 | +#endif | |
103 | + xki->page_list[PA_PTE_0] = __ma(kexec_pte0); | |
104 | + xki->page_list[PA_PTE_1] = __ma(kexec_pte1); | |
105 | + | |
106 | +} | |
107 | + | |
108 | +int __init machine_kexec_setup_resources(struct resource *hypervisor, | |
109 | + struct resource *phys_cpus, | |
110 | + int nr_phys_cpus) | |
111 | +{ | |
112 | + int k; | |
113 | + | |
114 | + /* The per-cpu crash note resources belong to the hypervisor resource */ | |
115 | + for (k = 0; k < nr_phys_cpus; k++) | |
116 | + request_resource(hypervisor, phys_cpus + k); | |
117 | + | |
118 | + return 0; | |
119 | +} | |
120 | + | |
121 | +void machine_kexec_register_resources(struct resource *res) { ; } | |
122 | + | |
123 | +#endif /* CONFIG_XEN */ | |
124 | + | |
125 | /* | |
126 | * A architecture hook called to validate the | |
127 | * proposed image and prepare the control pages | |
128 | @@ -64,6 +117,7 @@ void machine_kexec_cleanup(struct kimage | |
129 | set_pages_nx(image->control_code_page, 1); | |
130 | } | |
131 | ||
132 | +#ifndef CONFIG_XEN | |
133 | /* | |
134 | * Do not allocate memory (or fail in any way) in machine_kexec(). | |
135 | * We are past the point of no return, committed to rebooting now. | |
136 | @@ -137,6 +191,7 @@ void machine_kexec(struct kimage *image) | |
137 | ||
138 | __ftrace_enabled_restore(save_ftrace_enabled); | |
139 | } | |
140 | +#endif | |
141 | ||
142 | void arch_crash_save_vmcoreinfo(void) | |
143 | { | |
144 | Index: head-2008-11-25/arch/x86/kernel/vm86_32.c | |
145 | =================================================================== | |
146 | --- head-2008-11-25.orig/arch/x86/kernel/vm86_32.c 2008-11-25 12:33:06.000000000 +0100 | |
147 | +++ head-2008-11-25/arch/x86/kernel/vm86_32.c 2008-11-25 12:35:53.000000000 +0100 | |
148 | @@ -124,7 +124,9 @@ static int copy_vm86_regs_from_user(stru | |
149 | ||
150 | struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs) | |
151 | { | |
152 | +#ifndef CONFIG_X86_NO_TSS | |
153 | struct tss_struct *tss; | |
154 | +#endif | |
155 | struct pt_regs *ret; | |
156 | unsigned long tmp; | |
157 | ||
158 | @@ -147,12 +149,16 @@ struct pt_regs *save_v86_state(struct ke | |
159 | do_exit(SIGSEGV); | |
160 | } | |
161 | ||
162 | +#ifndef CONFIG_X86_NO_TSS | |
163 | tss = &per_cpu(init_tss, get_cpu()); | |
164 | +#endif | |
165 | current->thread.sp0 = current->thread.saved_sp0; | |
166 | current->thread.sysenter_cs = __KERNEL_CS; | |
167 | load_sp0(tss, ¤t->thread); | |
168 | current->thread.saved_sp0 = 0; | |
169 | +#ifndef CONFIG_X86_NO_TSS | |
170 | put_cpu(); | |
171 | +#endif | |
172 | ||
173 | ret = KVM86->regs32; | |
174 | ||
175 | @@ -279,7 +285,9 @@ out: | |
176 | ||
177 | static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) | |
178 | { | |
179 | +#ifndef CONFIG_X86_NO_TSS | |
180 | struct tss_struct *tss; | |
181 | +#endif | |
182 | /* | |
183 | * make sure the vm86() system call doesn't try to do anything silly | |
184 | */ | |
185 | @@ -324,12 +332,16 @@ static void do_sys_vm86(struct kernel_vm | |
186 | tsk->thread.saved_fs = info->regs32->fs; | |
187 | savesegment(gs, tsk->thread.saved_gs); | |
188 | ||
189 | +#ifndef CONFIG_X86_NO_TSS | |
190 | tss = &per_cpu(init_tss, get_cpu()); | |
191 | +#endif | |
192 | tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0; | |
193 | if (cpu_has_sep) | |
194 | tsk->thread.sysenter_cs = 0; | |
195 | load_sp0(tss, &tsk->thread); | |
196 | +#ifndef CONFIG_X86_NO_TSS | |
197 | put_cpu(); | |
198 | +#endif | |
199 | ||
200 | tsk->thread.screen_bitmap = info->screen_bitmap; | |
201 | if (info->flags & VM86_SCREEN_BITMAP) | |
202 | Index: head-2008-11-25/arch/x86/power/cpu_32.c | |
203 | =================================================================== | |
204 | --- head-2008-11-25.orig/arch/x86/power/cpu_32.c 2008-11-25 12:33:06.000000000 +0100 | |
205 | +++ head-2008-11-25/arch/x86/power/cpu_32.c 2008-11-25 12:35:53.000000000 +0100 | |
206 | @@ -65,6 +65,7 @@ static void do_fpu_end(void) | |
207 | ||
208 | static void fix_processor_context(void) | |
209 | { | |
210 | +#ifndef CONFIG_X86_NO_TSS | |
211 | int cpu = smp_processor_id(); | |
212 | struct tss_struct *t = &per_cpu(init_tss, cpu); | |
213 | ||
214 | @@ -74,6 +75,7 @@ static void fix_processor_context(void) | |
215 | * 386 hardware has concept of busy TSS or some | |
216 | * similar stupidity. | |
217 | */ | |
218 | +#endif | |
219 | ||
220 | load_TR_desc(); /* This does ltr */ | |
221 | load_LDT(¤t->active_mm->context); /* This does lldt */ | |
222 | Index: head-2008-11-25/arch/x86/vdso/vdso32-setup.c | |
223 | =================================================================== | |
224 | --- head-2008-11-25.orig/arch/x86/vdso/vdso32-setup.c 2008-11-25 12:33:06.000000000 +0100 | |
225 | +++ head-2008-11-25/arch/x86/vdso/vdso32-setup.c 2008-11-25 12:35:53.000000000 +0100 | |
226 | @@ -26,6 +26,10 @@ | |
227 | #include <asm/vdso.h> | |
228 | #include <asm/proto.h> | |
229 | ||
230 | +#ifdef CONFIG_XEN | |
231 | +#include <xen/interface/callback.h> | |
232 | +#endif | |
233 | + | |
234 | enum { | |
235 | VDSO_DISABLED = 0, | |
236 | VDSO_ENABLED = 1, | |
237 | @@ -225,6 +229,7 @@ static inline void map_compat_vdso(int m | |
238 | ||
239 | void enable_sep_cpu(void) | |
240 | { | |
241 | +#ifndef CONFIG_XEN | |
242 | int cpu = get_cpu(); | |
243 | struct tss_struct *tss = &per_cpu(init_tss, cpu); | |
244 | ||
245 | @@ -239,6 +244,35 @@ void enable_sep_cpu(void) | |
246 | wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.sp1, 0); | |
247 | wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) ia32_sysenter_target, 0); | |
248 | put_cpu(); | |
249 | +#else | |
250 | + extern asmlinkage void ia32pv_sysenter_target(void); | |
251 | + static struct callback_register sysenter = { | |
252 | + .type = CALLBACKTYPE_sysenter, | |
253 | + .address = { __KERNEL_CS, (unsigned long)ia32pv_sysenter_target }, | |
254 | + }; | |
255 | + | |
256 | + if (!boot_cpu_has(X86_FEATURE_SEP)) | |
257 | + return; | |
258 | + | |
259 | + get_cpu(); | |
260 | + | |
261 | + if (xen_feature(XENFEAT_supervisor_mode_kernel)) | |
262 | + sysenter.address.eip = (unsigned long)ia32_sysenter_target; | |
263 | + | |
264 | + switch (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter)) { | |
265 | + case 0: | |
266 | + break; | |
267 | +#if CONFIG_XEN_COMPAT < 0x030200 | |
268 | + case -ENOSYS: | |
269 | + sysenter.type = CALLBACKTYPE_sysenter_deprecated; | |
270 | + if (HYPERVISOR_callback_op(CALLBACKOP_register, &sysenter) == 0) | |
271 | + break; | |
272 | +#endif | |
273 | + default: | |
274 | + clear_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability); | |
275 | + break; | |
276 | + } | |
277 | +#endif | |
278 | } | |
279 | ||
280 | static struct vm_area_struct gate_vma; |