diff options
Diffstat (limited to 'arch/x86/lguest')
-rw-r--r-- | arch/x86/lguest/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/lguest/boot.c | 51 |
2 files changed, 27 insertions, 25 deletions
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig index 19626ace0f50..964dfa36d367 100644 --- a/arch/x86/lguest/Kconfig +++ b/arch/x86/lguest/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config LGUEST_GUEST | 1 | config LGUEST_GUEST |
2 | bool "Lguest guest support" | 2 | bool "Lguest guest support" |
3 | select PARAVIRT | 3 | select PARAVIRT |
4 | depends on X86_32 | ||
4 | depends on !X86_PAE | 5 | depends on !X86_PAE |
5 | depends on !(X86_VISWS || X86_VOYAGER) | 6 | depends on !(X86_VISWS || X86_VOYAGER) |
6 | select VIRTIO | 7 | select VIRTIO |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index d6b18e2e5431..5afdde4895dc 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -176,8 +176,8 @@ static void lguest_leave_lazy_mode(void) | |||
176 | * check there when it wants to deliver an interrupt. | 176 | * check there when it wants to deliver an interrupt. |
177 | */ | 177 | */ |
178 | 178 | ||
179 | /* save_flags() is expected to return the processor state (ie. "eflags"). The | 179 | /* save_flags() is expected to return the processor state (ie. "flags"). The |
180 | * eflags word contains all kind of stuff, but in practice Linux only cares | 180 | * flags word contains all kind of stuff, but in practice Linux only cares |
181 | * about the interrupt flag. Our "save_flags()" just returns that. */ | 181 | * about the interrupt flag. Our "save_flags()" just returns that. */ |
182 | static unsigned long save_fl(void) | 182 | static unsigned long save_fl(void) |
183 | { | 183 | { |
@@ -218,19 +218,20 @@ static void irq_enable(void) | |||
218 | * address of the handler, and... well, who cares? The Guest just asks the | 218 | * address of the handler, and... well, who cares? The Guest just asks the |
219 | * Host to make the change anyway, because the Host controls the real IDT. | 219 | * Host to make the change anyway, because the Host controls the real IDT. |
220 | */ | 220 | */ |
221 | static void lguest_write_idt_entry(struct desc_struct *dt, | 221 | static void lguest_write_idt_entry(gate_desc *dt, |
222 | int entrynum, u32 low, u32 high) | 222 | int entrynum, const gate_desc *g) |
223 | { | 223 | { |
224 | u32 *desc = (u32 *)g; | ||
224 | /* Keep the local copy up to date. */ | 225 | /* Keep the local copy up to date. */ |
225 | write_dt_entry(dt, entrynum, low, high); | 226 | native_write_idt_entry(dt, entrynum, g); |
226 | /* Tell Host about this new entry. */ | 227 | /* Tell Host about this new entry. */ |
227 | hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, low, high); | 228 | hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]); |
228 | } | 229 | } |
229 | 230 | ||
230 | /* Changing to a different IDT is very rare: we keep the IDT up-to-date every | 231 | /* Changing to a different IDT is very rare: we keep the IDT up-to-date every |
231 | * time it is written, so we can simply loop through all entries and tell the | 232 | * time it is written, so we can simply loop through all entries and tell the |
232 | * Host about them. */ | 233 | * Host about them. */ |
233 | static void lguest_load_idt(const struct Xgt_desc_struct *desc) | 234 | static void lguest_load_idt(const struct desc_ptr *desc) |
234 | { | 235 | { |
235 | unsigned int i; | 236 | unsigned int i; |
236 | struct desc_struct *idt = (void *)desc->address; | 237 | struct desc_struct *idt = (void *)desc->address; |
@@ -253,7 +254,7 @@ static void lguest_load_idt(const struct Xgt_desc_struct *desc) | |||
253 | * hypercall and use that repeatedly to load a new IDT. I don't think it | 254 | * hypercall and use that repeatedly to load a new IDT. I don't think it |
254 | * really matters, but wouldn't it be nice if they were the same? | 255 | * really matters, but wouldn't it be nice if they were the same? |
255 | */ | 256 | */ |
256 | static void lguest_load_gdt(const struct Xgt_desc_struct *desc) | 257 | static void lguest_load_gdt(const struct desc_ptr *desc) |
257 | { | 258 | { |
258 | BUG_ON((desc->size+1)/8 != GDT_ENTRIES); | 259 | BUG_ON((desc->size+1)/8 != GDT_ENTRIES); |
259 | hcall(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES, 0); | 260 | hcall(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES, 0); |
@@ -262,10 +263,10 @@ static void lguest_load_gdt(const struct Xgt_desc_struct *desc) | |||
262 | /* For a single GDT entry which changes, we do the lazy thing: alter our GDT, | 263 | /* For a single GDT entry which changes, we do the lazy thing: alter our GDT, |
263 | * then tell the Host to reload the entire thing. This operation is so rare | 264 | * then tell the Host to reload the entire thing. This operation is so rare |
264 | * that this naive implementation is reasonable. */ | 265 | * that this naive implementation is reasonable. */ |
265 | static void lguest_write_gdt_entry(struct desc_struct *dt, | 266 | static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, |
266 | int entrynum, u32 low, u32 high) | 267 | const void *desc, int type) |
267 | { | 268 | { |
268 | write_dt_entry(dt, entrynum, low, high); | 269 | native_write_gdt_entry(dt, entrynum, desc, type); |
269 | hcall(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES, 0); | 270 | hcall(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES, 0); |
270 | } | 271 | } |
271 | 272 | ||
@@ -324,30 +325,30 @@ static void lguest_load_tr_desc(void) | |||
324 | * anyone (including userspace) can just use the raw "cpuid" instruction and | 325 | * anyone (including userspace) can just use the raw "cpuid" instruction and |
325 | * the Host won't even notice since it isn't privileged. So we try not to get | 326 | * the Host won't even notice since it isn't privileged. So we try not to get |
326 | * too worked up about it. */ | 327 | * too worked up about it. */ |
327 | static void lguest_cpuid(unsigned int *eax, unsigned int *ebx, | 328 | static void lguest_cpuid(unsigned int *ax, unsigned int *bx, |
328 | unsigned int *ecx, unsigned int *edx) | 329 | unsigned int *cx, unsigned int *dx) |
329 | { | 330 | { |
330 | int function = *eax; | 331 | int function = *ax; |
331 | 332 | ||
332 | native_cpuid(eax, ebx, ecx, edx); | 333 | native_cpuid(ax, bx, cx, dx); |
333 | switch (function) { | 334 | switch (function) { |
334 | case 1: /* Basic feature request. */ | 335 | case 1: /* Basic feature request. */ |
335 | /* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */ | 336 | /* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */ |
336 | *ecx &= 0x00002201; | 337 | *cx &= 0x00002201; |
337 | /* SSE, SSE2, FXSR, MMX, CMOV, CMPXCHG8B, FPU. */ | 338 | /* SSE, SSE2, FXSR, MMX, CMOV, CMPXCHG8B, FPU. */ |
338 | *edx &= 0x07808101; | 339 | *dx &= 0x07808101; |
339 | /* The Host can do a nice optimization if it knows that the | 340 | /* The Host can do a nice optimization if it knows that the |
340 | * kernel mappings (addresses above 0xC0000000 or whatever | 341 | * kernel mappings (addresses above 0xC0000000 or whatever |
341 | * PAGE_OFFSET is set to) haven't changed. But Linux calls | 342 | * PAGE_OFFSET is set to) haven't changed. But Linux calls |
342 | * flush_tlb_user() for both user and kernel mappings unless | 343 | * flush_tlb_user() for both user and kernel mappings unless |
343 | * the Page Global Enable (PGE) feature bit is set. */ | 344 | * the Page Global Enable (PGE) feature bit is set. */ |
344 | *edx |= 0x00002000; | 345 | *dx |= 0x00002000; |
345 | break; | 346 | break; |
346 | case 0x80000000: | 347 | case 0x80000000: |
347 | /* Futureproof this a little: if they ask how much extended | 348 | /* Futureproof this a little: if they ask how much extended |
348 | * processor information there is, limit it to known fields. */ | 349 | * processor information there is, limit it to known fields. */ |
349 | if (*eax > 0x80000008) | 350 | if (*ax > 0x80000008) |
350 | *eax = 0x80000008; | 351 | *ax = 0x80000008; |
351 | break; | 352 | break; |
352 | } | 353 | } |
353 | } | 354 | } |
@@ -756,10 +757,10 @@ static void lguest_time_init(void) | |||
756 | * segment), the privilege level (we're privilege level 1, the Host is 0 and | 757 | * segment), the privilege level (we're privilege level 1, the Host is 0 and |
757 | * will not tolerate us trying to use that), the stack pointer, and the number | 758 | * will not tolerate us trying to use that), the stack pointer, and the number |
758 | * of pages in the stack. */ | 759 | * of pages in the stack. */ |
759 | static void lguest_load_esp0(struct tss_struct *tss, | 760 | static void lguest_load_sp0(struct tss_struct *tss, |
760 | struct thread_struct *thread) | 761 | struct thread_struct *thread) |
761 | { | 762 | { |
762 | lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->esp0, | 763 | lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->sp0, |
763 | THREAD_SIZE/PAGE_SIZE); | 764 | THREAD_SIZE/PAGE_SIZE); |
764 | } | 765 | } |
765 | 766 | ||
@@ -789,11 +790,11 @@ static void lguest_wbinvd(void) | |||
789 | * code qualifies for Advanced. It will also never interrupt anything. It | 790 | * code qualifies for Advanced. It will also never interrupt anything. It |
790 | * does, however, allow us to get through the Linux boot code. */ | 791 | * does, however, allow us to get through the Linux boot code. */ |
791 | #ifdef CONFIG_X86_LOCAL_APIC | 792 | #ifdef CONFIG_X86_LOCAL_APIC |
792 | static void lguest_apic_write(unsigned long reg, unsigned long v) | 793 | static void lguest_apic_write(unsigned long reg, u32 v) |
793 | { | 794 | { |
794 | } | 795 | } |
795 | 796 | ||
796 | static unsigned long lguest_apic_read(unsigned long reg) | 797 | static u32 lguest_apic_read(unsigned long reg) |
797 | { | 798 | { |
798 | return 0; | 799 | return 0; |
799 | } | 800 | } |
@@ -963,7 +964,7 @@ __init void lguest_init(void) | |||
963 | pv_cpu_ops.cpuid = lguest_cpuid; | 964 | pv_cpu_ops.cpuid = lguest_cpuid; |
964 | pv_cpu_ops.load_idt = lguest_load_idt; | 965 | pv_cpu_ops.load_idt = lguest_load_idt; |
965 | pv_cpu_ops.iret = lguest_iret; | 966 | pv_cpu_ops.iret = lguest_iret; |
966 | pv_cpu_ops.load_esp0 = lguest_load_esp0; | 967 | pv_cpu_ops.load_sp0 = lguest_load_sp0; |
967 | pv_cpu_ops.load_tr_desc = lguest_load_tr_desc; | 968 | pv_cpu_ops.load_tr_desc = lguest_load_tr_desc; |
968 | pv_cpu_ops.set_ldt = lguest_set_ldt; | 969 | pv_cpu_ops.set_ldt = lguest_set_ldt; |
969 | pv_cpu_ops.load_tls = lguest_load_tls; | 970 | pv_cpu_ops.load_tls = lguest_load_tls; |