aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86_emulate.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r--drivers/kvm/x86_emulate.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 73e3580c88e4..087a8208f873 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -63,8 +63,9 @@
63/* Destination is only written; never read. */ 63/* Destination is only written; never read. */
64#define Mov (1<<7) 64#define Mov (1<<7)
65#define BitOp (1<<8) 65#define BitOp (1<<8)
66#define MemAbs (1<<9) /* Memory operand is absolute displacement */
66 67
67static u8 opcode_table[256] = { 68static u16 opcode_table[256] = {
68 /* 0x00 - 0x07 */ 69 /* 0x00 - 0x07 */
69 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 70 ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
70 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, 71 ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
@@ -134,8 +135,8 @@ static u8 opcode_table[256] = {
134 /* 0x90 - 0x9F */ 135 /* 0x90 - 0x9F */
135 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps, ImplicitOps, 0, 0, 136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps, ImplicitOps, 0, 0,
136 /* 0xA0 - 0xA7 */ 137 /* 0xA0 - 0xA7 */
137 ByteOp | DstReg | SrcMem | Mov, DstReg | SrcMem | Mov, 138 ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs,
138 ByteOp | DstMem | SrcReg | Mov, DstMem | SrcReg | Mov, 139 ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs,
139 ByteOp | ImplicitOps | Mov, ImplicitOps | Mov, 140 ByteOp | ImplicitOps | Mov, ImplicitOps | Mov,
140 ByteOp | ImplicitOps, ImplicitOps, 141 ByteOp | ImplicitOps, ImplicitOps,
141 /* 0xA8 - 0xAF */ 142 /* 0xA8 - 0xAF */
@@ -755,16 +756,6 @@ done_prefixes:
755 break; 756 break;
756 } 757 }
757 } 758 }
758 if (!c->override_base)
759 c->override_base = &ctxt->ds_base;
760 if (mode == X86EMUL_MODE_PROT64 &&
761 c->override_base != &ctxt->fs_base &&
762 c->override_base != &ctxt->gs_base)
763 c->override_base = NULL;
764
765 if (c->override_base)
766 c->modrm_ea += *c->override_base;
767
768 if (rip_relative) { 759 if (rip_relative) {
769 c->modrm_ea += c->eip; 760 c->modrm_ea += c->eip;
770 switch (c->d & SrcMask) { 761 switch (c->d & SrcMask) {
@@ -781,12 +772,35 @@ done_prefixes:
781 c->modrm_ea += c->op_bytes; 772 c->modrm_ea += c->op_bytes;
782 } 773 }
783 } 774 }
784 if (c->ad_bytes != 8)
785 c->modrm_ea = (u32)c->modrm_ea;
786modrm_done: 775modrm_done:
787 ; 776 ;
777 } else if (c->d & MemAbs) {
778 switch (c->ad_bytes) {
779 case 2:
780 c->modrm_ea = insn_fetch(u16, 2, c->eip);
781 break;
782 case 4:
783 c->modrm_ea = insn_fetch(u32, 4, c->eip);
784 break;
785 case 8:
786 c->modrm_ea = insn_fetch(u64, 8, c->eip);
787 break;
788 }
789
788 } 790 }
789 791
792 if (!c->override_base)
793 c->override_base = &ctxt->ds_base;
794 if (mode == X86EMUL_MODE_PROT64 &&
795 c->override_base != &ctxt->fs_base &&
796 c->override_base != &ctxt->gs_base)
797 c->override_base = NULL;
798
799 if (c->override_base)
800 c->modrm_ea += *c->override_base;
801
802 if (c->ad_bytes != 8)
803 c->modrm_ea = (u32)c->modrm_ea;
790 /* 804 /*
791 * Decode and fetch the source operand: register, memory 805 * Decode and fetch the source operand: register, memory
792 * or immediate. 806 * or immediate.
@@ -1171,7 +1185,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1171 memcpy(c->regs, ctxt->vcpu->regs, sizeof c->regs); 1185 memcpy(c->regs, ctxt->vcpu->regs, sizeof c->regs);
1172 saved_eip = c->eip; 1186 saved_eip = c->eip;
1173 1187
1174 if ((c->d & ModRM) && (c->modrm_mod != 3)) 1188 if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs))
1175 cr2 = c->modrm_ea; 1189 cr2 = c->modrm_ea;
1176 1190
1177 if (c->src.type == OP_MEM) { 1191 if (c->src.type == OP_MEM) {
@@ -1326,13 +1340,9 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1326 case 0xa0 ... 0xa1: /* mov */ 1340 case 0xa0 ... 0xa1: /* mov */
1327 c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; 1341 c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
1328 c->dst.val = c->src.val; 1342 c->dst.val = c->src.val;
1329 /* skip src displacement */
1330 c->eip += c->ad_bytes;
1331 break; 1343 break;
1332 case 0xa2 ... 0xa3: /* mov */ 1344 case 0xa2 ... 0xa3: /* mov */
1333 c->dst.val = (unsigned long)c->regs[VCPU_REGS_RAX]; 1345 c->dst.val = (unsigned long)c->regs[VCPU_REGS_RAX];
1334 /* skip c->dst displacement */
1335 c->eip += c->ad_bytes;
1336 break; 1346 break;
1337 case 0xc0 ... 0xc1: 1347 case 0xc0 ... 0xc1:
1338 emulate_grp2(ctxt); 1348 emulate_grp2(ctxt);