]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/kvm/x86_emulate.c
Input: add driver for Fujitsu application buttons
[linux-2.6-omap-h63xx.git] / drivers / kvm / x86_emulate.c
index 9737c3b2f48c1a2006cd6420ce192f04a323c7e3..a6ace302e0cd454f1f413306013b0920305e4a67 100644 (file)
@@ -212,7 +212,8 @@ static u16 twobyte_table[256] = {
        0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
            DstReg | SrcMem16 | ModRM | Mov,
        /* 0xC0 - 0xCF */
-       0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
+       0, 0, 0, 0, 0, 0, 0, 0,
        /* 0xD0 - 0xDF */
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        /* 0xE0 - 0xEF */
@@ -596,11 +597,10 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
                case 0xf0:      /* LOCK */
                        lock_prefix = 1;
                        break;
+               case 0xf2:      /* REPNE/REPNZ */
                case 0xf3:      /* REP/REPE/REPZ */
                        rep_prefix = 1;
                        break;
-               case 0xf2:      /* REPNE/REPNZ */
-                       break;
                default:
                        goto done_prefixes;
                }
@@ -825,6 +825,14 @@ done_prefixes:
                if (twobyte && b == 0x01 && modrm_reg == 7)
                        break;
              srcmem_common:
+               /*
+                * For instructions with a ModR/M byte, switch to register
+                * access if Mod = 3.
+                */
+               if ((d & ModRM) && modrm_mod == 3) {
+                       src.type = OP_REG;
+                       break;
+               }
                src.type = OP_MEM;
                src.ptr = (unsigned long *)cr2;
                src.val = 0;
@@ -893,6 +901,14 @@ done_prefixes:
                dst.ptr = (unsigned long *)cr2;
                dst.bytes = (d & ByteOp) ? 1 : op_bytes;
                dst.val = 0;
+               /*
+                * For instructions with a ModR/M byte, switch to register
+                * access if Mod = 3.
+                */
+               if ((d & ModRM) && modrm_mod == 3) {
+                       dst.type = OP_REG;
+                       break;
+               }
                if (d & BitOp) {
                        unsigned long mask = ~(dst.bytes * 8 - 1);
 
@@ -1083,31 +1099,6 @@ push:
        case 0xd2 ... 0xd3:     /* Grp2 */
                src.val = _regs[VCPU_REGS_RCX];
                goto grp2;
-       case 0xe8: /* call (near) */ {
-               long int rel;
-               switch (op_bytes) {
-               case 2:
-                       rel = insn_fetch(s16, 2, _eip);
-                       break;
-               case 4:
-                       rel = insn_fetch(s32, 4, _eip);
-                       break;
-               case 8:
-                       rel = insn_fetch(s64, 8, _eip);
-                       break;
-               default:
-                       DPRINTF("Call: Invalid op_bytes\n");
-                       goto cannot_emulate;
-               }
-               src.val = (unsigned long) _eip;
-               JMP_REL(rel);
-               goto push;
-       }
-       case 0xe9: /* jmp rel */
-       case 0xeb: /* jmp rel short */
-               JMP_REL(src.val);
-               no_wb = 1; /* Disable writeback. */
-               break;
        case 0xf6 ... 0xf7:     /* Grp3 */
                switch (modrm_reg) {
                case 0 ... 1:   /* test */
@@ -1350,6 +1341,32 @@ special_insn:
        case 0xae ... 0xaf:     /* scas */
                DPRINTF("Urk! I don't handle SCAS.\n");
                goto cannot_emulate;
+       case 0xe8: /* call (near) */ {
+               long int rel;
+               switch (op_bytes) {
+               case 2:
+                       rel = insn_fetch(s16, 2, _eip);
+                       break;
+               case 4:
+                       rel = insn_fetch(s32, 4, _eip);
+                       break;
+               case 8:
+                       rel = insn_fetch(s64, 8, _eip);
+                       break;
+               default:
+                       DPRINTF("Call: Invalid op_bytes\n");
+                       goto cannot_emulate;
+               }
+               src.val = (unsigned long) _eip;
+               JMP_REL(rel);
+               goto push;
+       }
+       case 0xe9: /* jmp rel */
+       case 0xeb: /* jmp rel short */
+               JMP_REL(src.val);
+               no_wb = 1; /* Disable writeback. */
+               break;
+
 
        }
        goto writeback;
@@ -1501,6 +1518,10 @@ twobyte_insn:
                dst.bytes = op_bytes;
                dst.val = (d & ByteOp) ? (s8) src.val : (s16) src.val;
                break;
+       case 0xc3:              /* movnti */
+               dst.bytes = op_bytes;
+               dst.val = (op_bytes == 4) ? (u32) src.val : (u64) src.val;
+               break;
        }
        goto writeback;