Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / drivers / lguest / x86 / core.c
index ec0cdfc..65af42f 100644 (file)
@@ -269,10 +269,10 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
 static int emulate_insn(struct lg_cpu *cpu)
 {
        u8 insn;
-       unsigned int insnlen = 0, in = 0, shift = 0;
+       unsigned int insnlen = 0, in = 0, small_operand = 0;
        /*
         * The eip contains the *virtual* address of the Guest's instruction:
-        * guest_pa just subtracts the Guest's page_offset.
+        * walk the Guest's page tables to find the "physical" address.
         */
        unsigned long physaddr = guest_pa(cpu, cpu->regs->eip);
 
@@ -300,11 +300,10 @@ static int emulate_insn(struct lg_cpu *cpu)
        }
 
        /*
-        * 0x66 is an "operand prefix".  It means it's using the upper 16 bits
-        * of the eax register.
+        * 0x66 is an "operand prefix".  It means a 16, not 32 bit in/out.
         */
        if (insn == 0x66) {
-               shift = 16;
+               small_operand = 1;
                /* The instruction is 1 byte so far, read the next byte. */
                insnlen = 1;
                insn = lgread(cpu, physaddr + insnlen, u8);
@@ -340,11 +339,14 @@ static int emulate_insn(struct lg_cpu *cpu)
         * traditionally means "there's nothing there".
         */
        if (in) {
-               /* Lower bit tells is whether it's a 16 or 32 bit access */
-               if (insn & 0x1)
-                       cpu->regs->eax = 0xFFFFFFFF;
-               else
-                       cpu->regs->eax |= (0xFFFF << shift);
+               /* Lower bit tells means it's a 32/16 bit access */
+               if (insn & 0x1) {
+                       if (small_operand)
+                               cpu->regs->eax |= 0xFFFF;
+                       else
+                               cpu->regs->eax = 0xFFFFFFFF;
+               } else
+                       cpu->regs->eax |= 0xFF;
        }
        /* Finally, we've "done" the instruction, so move past it. */
        cpu->regs->eip += insnlen;
@@ -409,7 +411,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
                 * These values mean a real interrupt occurred, in which case
                 * the Host handler has already been run. We just do a
                 * friendly check if another process should now be run, then
-                * return to run the Guest again
+                * return to run the Guest again.
                 */
                cond_resched();
                return;
@@ -459,7 +461,7 @@ void __init lguest_arch_host_init(void)
        int i;
 
        /*
-        * Most of the i386/switcher.S doesn't care that it's been moved; on
+        * Most of the x86/switcher_32.S doesn't care that it's been moved; on
         * Intel, jumps are relative, and it doesn't access any references to
         * external code or data.
         *
@@ -587,7 +589,7 @@ void __init lguest_arch_host_init(void)
                clear_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE);
        }
        put_online_cpus();
-};
+}
 /*:*/
 
 void __exit lguest_arch_host_fini(void)
@@ -670,8 +672,6 @@ int lguest_arch_init_hypercalls(struct lg_cpu *cpu)
 /*:*/
 
 /*L:030
- * lguest_arch_setup_regs()
- *
  * Most of the Guest's registers are left alone: we used get_zeroed_page() to
  * allocate the structure, so they will be 0.
  */