aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/lguest
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/lguest')
-rw-r--r--arch/x86/lguest/Kconfig1
-rw-r--r--arch/x86/lguest/boot.c51
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 @@
1config LGUEST_GUEST 1config 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. */
182static unsigned long save_fl(void) 182static 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 */
221static void lguest_write_idt_entry(struct desc_struct *dt, 221static 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. */
233static void lguest_load_idt(const struct Xgt_desc_struct *desc) 234static 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 */
256static void lguest_load_gdt(const struct Xgt_desc_struct *desc) 257static 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. */
265static void lguest_write_gdt_entry(struct desc_struct *dt, 266static 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. */
327static void lguest_cpuid(unsigned int *eax, unsigned int *ebx, 328static 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. */
759static void lguest_load_esp0(struct tss_struct *tss, 760static 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
792static void lguest_apic_write(unsigned long reg, unsigned long v) 793static void lguest_apic_write(unsigned long reg, u32 v)
793{ 794{
794} 795}
795 796
796static unsigned long lguest_apic_read(unsigned long reg) 797static 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;