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.c77
1 files changed, 49 insertions, 28 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 9737c3b2f48c..a6ace302e0cd 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -212,7 +212,8 @@ static u16 twobyte_table[256] = {
212 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, 212 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
213 DstReg | SrcMem16 | ModRM | Mov, 213 DstReg | SrcMem16 | ModRM | Mov,
214 /* 0xC0 - 0xCF */ 214 /* 0xC0 - 0xCF */
215 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, 0, 215 0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
216 0, 0, 0, 0, 0, 0, 0, 0,
216 /* 0xD0 - 0xDF */ 217 /* 0xD0 - 0xDF */
217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 /* 0xE0 - 0xEF */ 219 /* 0xE0 - 0xEF */
@@ -596,11 +597,10 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
596 case 0xf0: /* LOCK */ 597 case 0xf0: /* LOCK */
597 lock_prefix = 1; 598 lock_prefix = 1;
598 break; 599 break;
600 case 0xf2: /* REPNE/REPNZ */
599 case 0xf3: /* REP/REPE/REPZ */ 601 case 0xf3: /* REP/REPE/REPZ */
600 rep_prefix = 1; 602 rep_prefix = 1;
601 break; 603 break;
602 case 0xf2: /* REPNE/REPNZ */
603 break;
604 default: 604 default:
605 goto done_prefixes; 605 goto done_prefixes;
606 } 606 }
@@ -825,6 +825,14 @@ done_prefixes:
825 if (twobyte && b == 0x01 && modrm_reg == 7) 825 if (twobyte && b == 0x01 && modrm_reg == 7)
826 break; 826 break;
827 srcmem_common: 827 srcmem_common:
828 /*
829 * For instructions with a ModR/M byte, switch to register
830 * access if Mod = 3.
831 */
832 if ((d & ModRM) && modrm_mod == 3) {
833 src.type = OP_REG;
834 break;
835 }
828 src.type = OP_MEM; 836 src.type = OP_MEM;
829 src.ptr = (unsigned long *)cr2; 837 src.ptr = (unsigned long *)cr2;
830 src.val = 0; 838 src.val = 0;
@@ -893,6 +901,14 @@ done_prefixes:
893 dst.ptr = (unsigned long *)cr2; 901 dst.ptr = (unsigned long *)cr2;
894 dst.bytes = (d & ByteOp) ? 1 : op_bytes; 902 dst.bytes = (d & ByteOp) ? 1 : op_bytes;
895 dst.val = 0; 903 dst.val = 0;
904 /*
905 * For instructions with a ModR/M byte, switch to register
906 * access if Mod = 3.
907 */
908 if ((d & ModRM) && modrm_mod == 3) {
909 dst.type = OP_REG;
910 break;
911 }
896 if (d & BitOp) { 912 if (d & BitOp) {
897 unsigned long mask = ~(dst.bytes * 8 - 1); 913 unsigned long mask = ~(dst.bytes * 8 - 1);
898 914
@@ -1083,31 +1099,6 @@ push:
1083 case 0xd2 ... 0xd3: /* Grp2 */ 1099 case 0xd2 ... 0xd3: /* Grp2 */
1084 src.val = _regs[VCPU_REGS_RCX]; 1100 src.val = _regs[VCPU_REGS_RCX];
1085 goto grp2; 1101 goto grp2;
1086 case 0xe8: /* call (near) */ {
1087 long int rel;
1088 switch (op_bytes) {
1089 case 2:
1090 rel = insn_fetch(s16, 2, _eip);
1091 break;
1092 case 4:
1093 rel = insn_fetch(s32, 4, _eip);
1094 break;
1095 case 8:
1096 rel = insn_fetch(s64, 8, _eip);
1097 break;
1098 default:
1099 DPRINTF("Call: Invalid op_bytes\n");
1100 goto cannot_emulate;
1101 }
1102 src.val = (unsigned long) _eip;
1103 JMP_REL(rel);
1104 goto push;
1105 }
1106 case 0xe9: /* jmp rel */
1107 case 0xeb: /* jmp rel short */
1108 JMP_REL(src.val);
1109 no_wb = 1; /* Disable writeback. */
1110 break;
1111 case 0xf6 ... 0xf7: /* Grp3 */ 1102 case 0xf6 ... 0xf7: /* Grp3 */
1112 switch (modrm_reg) { 1103 switch (modrm_reg) {
1113 case 0 ... 1: /* test */ 1104 case 0 ... 1: /* test */
@@ -1350,6 +1341,32 @@ special_insn:
1350 case 0xae ... 0xaf: /* scas */ 1341 case 0xae ... 0xaf: /* scas */
1351 DPRINTF("Urk! I don't handle SCAS.\n"); 1342 DPRINTF("Urk! I don't handle SCAS.\n");
1352 goto cannot_emulate; 1343 goto cannot_emulate;
1344 case 0xe8: /* call (near) */ {
1345 long int rel;
1346 switch (op_bytes) {
1347 case 2:
1348 rel = insn_fetch(s16, 2, _eip);
1349 break;
1350 case 4:
1351 rel = insn_fetch(s32, 4, _eip);
1352 break;
1353 case 8:
1354 rel = insn_fetch(s64, 8, _eip);
1355 break;
1356 default:
1357 DPRINTF("Call: Invalid op_bytes\n");
1358 goto cannot_emulate;
1359 }
1360 src.val = (unsigned long) _eip;
1361 JMP_REL(rel);
1362 goto push;
1363 }
1364 case 0xe9: /* jmp rel */
1365 case 0xeb: /* jmp rel short */
1366 JMP_REL(src.val);
1367 no_wb = 1; /* Disable writeback. */
1368 break;
1369
1353 1370
1354 } 1371 }
1355 goto writeback; 1372 goto writeback;
@@ -1501,6 +1518,10 @@ twobyte_insn:
1501 dst.bytes = op_bytes; 1518 dst.bytes = op_bytes;
1502 dst.val = (d & ByteOp) ? (s8) src.val : (s16) src.val; 1519 dst.val = (d & ByteOp) ? (s8) src.val : (s16) src.val;
1503 break; 1520 break;
1521 case 0xc3: /* movnti */
1522 dst.bytes = op_bytes;
1523 dst.val = (op_bytes == 4) ? (u32) src.val : (u64) src.val;
1524 break;
1504 } 1525 }
1505 goto writeback; 1526 goto writeback;
1506 1527