diff options
author | Laurent Vivier <Laurent.Vivier@bull.net> | 2007-09-24 05:10:55 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:52:48 -0500 |
commit | 05f086f87ef17da70d5f4e9b063e9ea31ab20f28 (patch) | |
tree | e55091bf167c72631ea29b5d3a32045097dd779a /drivers/kvm/x86_emulate.c | |
parent | 8cdbd2c9bf3108c41563eef586f22fa8b5174de0 (diff) |
KVM: x86 emulator: remove _eflags and use directly ctxt->eflags.
Remove _eflags and use directly ctxt->eflags. Caching eflags is not needed as
it is restored to vcpu by kvm_main.c:emulate_instruction() from ctxt->eflags
only if emulation doesn't fail.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r-- | drivers/kvm/x86_emulate.c | 121 |
1 files changed, 59 insertions, 62 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index a15609279283..76b813b6365c 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c | |||
@@ -941,37 +941,37 @@ static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, | |||
941 | return 0; | 941 | return 0; |
942 | } | 942 | } |
943 | 943 | ||
944 | static inline void emulate_grp2(struct decode_cache *c, unsigned long *_eflags) | 944 | static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt) |
945 | { | 945 | { |
946 | struct decode_cache *c = &ctxt->decode; | ||
946 | switch (c->modrm_reg) { | 947 | switch (c->modrm_reg) { |
947 | case 0: /* rol */ | 948 | case 0: /* rol */ |
948 | emulate_2op_SrcB("rol", c->src, c->dst, *_eflags); | 949 | emulate_2op_SrcB("rol", c->src, c->dst, ctxt->eflags); |
949 | break; | 950 | break; |
950 | case 1: /* ror */ | 951 | case 1: /* ror */ |
951 | emulate_2op_SrcB("ror", c->src, c->dst, *_eflags); | 952 | emulate_2op_SrcB("ror", c->src, c->dst, ctxt->eflags); |
952 | break; | 953 | break; |
953 | case 2: /* rcl */ | 954 | case 2: /* rcl */ |
954 | emulate_2op_SrcB("rcl", c->src, c->dst, *_eflags); | 955 | emulate_2op_SrcB("rcl", c->src, c->dst, ctxt->eflags); |
955 | break; | 956 | break; |
956 | case 3: /* rcr */ | 957 | case 3: /* rcr */ |
957 | emulate_2op_SrcB("rcr", c->src, c->dst, *_eflags); | 958 | emulate_2op_SrcB("rcr", c->src, c->dst, ctxt->eflags); |
958 | break; | 959 | break; |
959 | case 4: /* sal/shl */ | 960 | case 4: /* sal/shl */ |
960 | case 6: /* sal/shl */ | 961 | case 6: /* sal/shl */ |
961 | emulate_2op_SrcB("sal", c->src, c->dst, *_eflags); | 962 | emulate_2op_SrcB("sal", c->src, c->dst, ctxt->eflags); |
962 | break; | 963 | break; |
963 | case 5: /* shr */ | 964 | case 5: /* shr */ |
964 | emulate_2op_SrcB("shr", c->src, c->dst, *_eflags); | 965 | emulate_2op_SrcB("shr", c->src, c->dst, ctxt->eflags); |
965 | break; | 966 | break; |
966 | case 7: /* sar */ | 967 | case 7: /* sar */ |
967 | emulate_2op_SrcB("sar", c->src, c->dst, *_eflags); | 968 | emulate_2op_SrcB("sar", c->src, c->dst, ctxt->eflags); |
968 | break; | 969 | break; |
969 | } | 970 | } |
970 | } | 971 | } |
971 | 972 | ||
972 | static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, | 973 | static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, |
973 | struct x86_emulate_ops *ops, | 974 | struct x86_emulate_ops *ops) |
974 | unsigned long *_eflags) | ||
975 | { | 975 | { |
976 | struct decode_cache *c = &ctxt->decode; | 976 | struct decode_cache *c = &ctxt->decode; |
977 | int rc = 0; | 977 | int rc = 0; |
@@ -998,13 +998,13 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, | |||
998 | c->src.val = insn_fetch(s32, 4, c->eip); | 998 | c->src.val = insn_fetch(s32, 4, c->eip); |
999 | break; | 999 | break; |
1000 | } | 1000 | } |
1001 | emulate_2op_SrcV("test", c->src, c->dst, *_eflags); | 1001 | emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags); |
1002 | break; | 1002 | break; |
1003 | case 2: /* not */ | 1003 | case 2: /* not */ |
1004 | c->dst.val = ~c->dst.val; | 1004 | c->dst.val = ~c->dst.val; |
1005 | break; | 1005 | break; |
1006 | case 3: /* neg */ | 1006 | case 3: /* neg */ |
1007 | emulate_1op("neg", c->dst, *_eflags); | 1007 | emulate_1op("neg", c->dst, ctxt->eflags); |
1008 | break; | 1008 | break; |
1009 | default: | 1009 | default: |
1010 | DPRINTF("Cannot emulate %02x\n", c->b); | 1010 | DPRINTF("Cannot emulate %02x\n", c->b); |
@@ -1017,7 +1017,6 @@ done: | |||
1017 | 1017 | ||
1018 | static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, | 1018 | static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, |
1019 | struct x86_emulate_ops *ops, | 1019 | struct x86_emulate_ops *ops, |
1020 | unsigned long *_eflags, | ||
1021 | int *no_wb) | 1020 | int *no_wb) |
1022 | { | 1021 | { |
1023 | struct decode_cache *c = &ctxt->decode; | 1022 | struct decode_cache *c = &ctxt->decode; |
@@ -1025,10 +1024,10 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, | |||
1025 | 1024 | ||
1026 | switch (c->modrm_reg) { | 1025 | switch (c->modrm_reg) { |
1027 | case 0: /* inc */ | 1026 | case 0: /* inc */ |
1028 | emulate_1op("inc", c->dst, *_eflags); | 1027 | emulate_1op("inc", c->dst, ctxt->eflags); |
1029 | break; | 1028 | break; |
1030 | case 1: /* dec */ | 1029 | case 1: /* dec */ |
1031 | emulate_1op("dec", c->dst, *_eflags); | 1030 | emulate_1op("dec", c->dst, ctxt->eflags); |
1032 | break; | 1031 | break; |
1033 | case 4: /* jmp abs */ | 1032 | case 4: /* jmp abs */ |
1034 | if (c->b == 0xff) | 1033 | if (c->b == 0xff) |
@@ -1067,7 +1066,6 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, | |||
1067 | 1066 | ||
1068 | static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | 1067 | static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, |
1069 | struct x86_emulate_ops *ops, | 1068 | struct x86_emulate_ops *ops, |
1070 | unsigned long *_eflags, | ||
1071 | unsigned long cr2) | 1069 | unsigned long cr2) |
1072 | { | 1070 | { |
1073 | struct decode_cache *c = &ctxt->decode; | 1071 | struct decode_cache *c = &ctxt->decode; |
@@ -1083,7 +1081,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | |||
1083 | 1081 | ||
1084 | c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); | 1082 | c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); |
1085 | c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); | 1083 | c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); |
1086 | *_eflags &= ~EFLG_ZF; | 1084 | ctxt->eflags &= ~EFLG_ZF; |
1087 | 1085 | ||
1088 | } else { | 1086 | } else { |
1089 | new = ((u64)c->regs[VCPU_REGS_RCX] << 32) | | 1087 | new = ((u64)c->regs[VCPU_REGS_RCX] << 32) | |
@@ -1092,7 +1090,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, | |||
1092 | rc = ops->cmpxchg_emulated(cr2, &old, &new, 8, ctxt->vcpu); | 1090 | rc = ops->cmpxchg_emulated(cr2, &old, &new, 8, ctxt->vcpu); |
1093 | if (rc != 0) | 1091 | if (rc != 0) |
1094 | return rc; | 1092 | return rc; |
1095 | *_eflags |= EFLG_ZF; | 1093 | ctxt->eflags |= EFLG_ZF; |
1096 | } | 1094 | } |
1097 | return 0; | 1095 | return 0; |
1098 | } | 1096 | } |
@@ -1152,7 +1150,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1152 | int no_wb = 0; | 1150 | int no_wb = 0; |
1153 | u64 msr_data; | 1151 | u64 msr_data; |
1154 | unsigned long saved_eip = 0; | 1152 | unsigned long saved_eip = 0; |
1155 | unsigned long _eflags = ctxt->eflags; | ||
1156 | struct decode_cache *c = &ctxt->decode; | 1153 | struct decode_cache *c = &ctxt->decode; |
1157 | int rc = 0; | 1154 | int rc = 0; |
1158 | 1155 | ||
@@ -1207,23 +1204,23 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1207 | switch (c->b) { | 1204 | switch (c->b) { |
1208 | case 0x00 ... 0x05: | 1205 | case 0x00 ... 0x05: |
1209 | add: /* add */ | 1206 | add: /* add */ |
1210 | emulate_2op_SrcV("add", c->src, c->dst, _eflags); | 1207 | emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags); |
1211 | break; | 1208 | break; |
1212 | case 0x08 ... 0x0d: | 1209 | case 0x08 ... 0x0d: |
1213 | or: /* or */ | 1210 | or: /* or */ |
1214 | emulate_2op_SrcV("or", c->src, c->dst, _eflags); | 1211 | emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags); |
1215 | break; | 1212 | break; |
1216 | case 0x10 ... 0x15: | 1213 | case 0x10 ... 0x15: |
1217 | adc: /* adc */ | 1214 | adc: /* adc */ |
1218 | emulate_2op_SrcV("adc", c->src, c->dst, _eflags); | 1215 | emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags); |
1219 | break; | 1216 | break; |
1220 | case 0x18 ... 0x1d: | 1217 | case 0x18 ... 0x1d: |
1221 | sbb: /* sbb */ | 1218 | sbb: /* sbb */ |
1222 | emulate_2op_SrcV("sbb", c->src, c->dst, _eflags); | 1219 | emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags); |
1223 | break; | 1220 | break; |
1224 | case 0x20 ... 0x23: | 1221 | case 0x20 ... 0x23: |
1225 | and: /* and */ | 1222 | and: /* and */ |
1226 | emulate_2op_SrcV("and", c->src, c->dst, _eflags); | 1223 | emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags); |
1227 | break; | 1224 | break; |
1228 | case 0x24: /* and al imm8 */ | 1225 | case 0x24: /* and al imm8 */ |
1229 | c->dst.type = OP_REG; | 1226 | c->dst.type = OP_REG; |
@@ -1244,15 +1241,15 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1244 | goto and; | 1241 | goto and; |
1245 | case 0x28 ... 0x2d: | 1242 | case 0x28 ... 0x2d: |
1246 | sub: /* sub */ | 1243 | sub: /* sub */ |
1247 | emulate_2op_SrcV("sub", c->src, c->dst, _eflags); | 1244 | emulate_2op_SrcV("sub", c->src, c->dst, ctxt->eflags); |
1248 | break; | 1245 | break; |
1249 | case 0x30 ... 0x35: | 1246 | case 0x30 ... 0x35: |
1250 | xor: /* xor */ | 1247 | xor: /* xor */ |
1251 | emulate_2op_SrcV("xor", c->src, c->dst, _eflags); | 1248 | emulate_2op_SrcV("xor", c->src, c->dst, ctxt->eflags); |
1252 | break; | 1249 | break; |
1253 | case 0x38 ... 0x3d: | 1250 | case 0x38 ... 0x3d: |
1254 | cmp: /* cmp */ | 1251 | cmp: /* cmp */ |
1255 | emulate_2op_SrcV("cmp", c->src, c->dst, _eflags); | 1252 | emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags); |
1256 | break; | 1253 | break; |
1257 | case 0x63: /* movsxd */ | 1254 | case 0x63: /* movsxd */ |
1258 | if (ctxt->mode != X86EMUL_MODE_PROT64) | 1255 | if (ctxt->mode != X86EMUL_MODE_PROT64) |
@@ -1280,7 +1277,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1280 | } | 1277 | } |
1281 | break; | 1278 | break; |
1282 | case 0x84 ... 0x85: | 1279 | case 0x84 ... 0x85: |
1283 | emulate_2op_SrcV("test", c->src, c->dst, _eflags); | 1280 | emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags); |
1284 | break; | 1281 | break; |
1285 | case 0x86 ... 0x87: /* xchg */ | 1282 | case 0x86 ... 0x87: /* xchg */ |
1286 | /* Write back the register source. */ | 1283 | /* Write back the register source. */ |
@@ -1327,7 +1324,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1327 | c->eip += c->ad_bytes; | 1324 | c->eip += c->ad_bytes; |
1328 | break; | 1325 | break; |
1329 | case 0xc0 ... 0xc1: | 1326 | case 0xc0 ... 0xc1: |
1330 | emulate_grp2(c, &_eflags); | 1327 | emulate_grp2(ctxt); |
1331 | break; | 1328 | break; |
1332 | case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ | 1329 | case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ |
1333 | mov: | 1330 | mov: |
@@ -1335,19 +1332,19 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
1335 | break; | 1332 | break; |
1336 | case 0xd0 ... 0xd1: /* Grp2 */ | 1333 | case 0xd0 ... 0xd1: /* Grp2 */ |
1337 | c->src.val = 1; | 1334 | c->src.val = 1; |
1338 | emulate_grp2(c, &_eflags); | 1335 | emulate_grp2(ctxt); |
1339 | break; | 1336 | break; |
1340 | case 0xd2 ... 0xd3: /* Grp2 */ | 1337 | case 0xd2 ... 0xd3: /* Grp2 */ |
1341 | c->src.val = c->regs[VCPU_REGS_RCX]; | 1338 | c->src.val = c->regs[VCPU_REGS_RCX]; |
1342 | emulate_grp2(c, &_eflags); | 1339 | emulate_grp2(ctxt); |
1343 | break; | 1340 | break; |
1344 | case 0xf6 ... 0xf7: /* Grp3 */ | 1341 | case 0xf6 ... 0xf7: /* Grp3 */ |
1345 | rc = emulate_grp3(ctxt, ops, &_eflags); | 1342 | rc = emulate_grp3(ctxt, ops); |
1346 | if (rc != 0) | 1343 | if (rc != 0) |
1347 | goto done; | 1344 | goto done; |
1348 | break; | 1345 | break; |
1349 | case 0xfe ... 0xff: /* Grp4/Grp5 */ | 1346 | case 0xfe ... 0xff: /* Grp4/Grp5 */ |
1350 | rc = emulate_grp45(ctxt, ops, &_eflags, &no_wb); | 1347 | rc = emulate_grp45(ctxt, ops, &no_wb); |
1351 | if (rc != 0) | 1348 | if (rc != 0) |
1352 | goto done; | 1349 | goto done; |
1353 | break; | 1350 | break; |
@@ -1362,7 +1359,6 @@ writeback: | |||
1362 | 1359 | ||
1363 | /* Commit shadow register state. */ | 1360 | /* Commit shadow register state. */ |
1364 | memcpy(ctxt->vcpu->regs, c->regs, sizeof c->regs); | 1361 | memcpy(ctxt->vcpu->regs, c->regs, sizeof c->regs); |
1365 | ctxt->eflags = _eflags; | ||
1366 | ctxt->vcpu->rip = c->eip; | 1362 | ctxt->vcpu->rip = c->eip; |
1367 | 1363 | ||
1368 | done: | 1364 | done: |
@@ -1413,7 +1409,7 @@ special_insn: | |||
1413 | (c->d & ByteOp) ? 1 : c->op_bytes, | 1409 | (c->d & ByteOp) ? 1 : c->op_bytes, |
1414 | c->rep_prefix ? | 1410 | c->rep_prefix ? |
1415 | address_mask(c->regs[VCPU_REGS_RCX]) : 1, | 1411 | address_mask(c->regs[VCPU_REGS_RCX]) : 1, |
1416 | (_eflags & EFLG_DF), | 1412 | (ctxt->eflags & EFLG_DF), |
1417 | register_address(ctxt->es_base, | 1413 | register_address(ctxt->es_base, |
1418 | c->regs[VCPU_REGS_RDI]), | 1414 | c->regs[VCPU_REGS_RDI]), |
1419 | c->rep_prefix, | 1415 | c->rep_prefix, |
@@ -1429,7 +1425,7 @@ special_insn: | |||
1429 | (c->d & ByteOp) ? 1 : c->op_bytes, | 1425 | (c->d & ByteOp) ? 1 : c->op_bytes, |
1430 | c->rep_prefix ? | 1426 | c->rep_prefix ? |
1431 | address_mask(c->regs[VCPU_REGS_RCX]) : 1, | 1427 | address_mask(c->regs[VCPU_REGS_RCX]) : 1, |
1432 | (_eflags & EFLG_DF), | 1428 | (ctxt->eflags & EFLG_DF), |
1433 | register_address(c->override_base ? | 1429 | register_address(c->override_base ? |
1434 | *c->override_base : | 1430 | *c->override_base : |
1435 | ctxt->ds_base, | 1431 | ctxt->ds_base, |
@@ -1443,16 +1439,16 @@ special_insn: | |||
1443 | case 0x70 ... 0x7f: /* jcc (short) */ { | 1439 | case 0x70 ... 0x7f: /* jcc (short) */ { |
1444 | int rel = insn_fetch(s8, 1, c->eip); | 1440 | int rel = insn_fetch(s8, 1, c->eip); |
1445 | 1441 | ||
1446 | if (test_cc(c->b, _eflags)) | 1442 | if (test_cc(c->b, ctxt->eflags)) |
1447 | JMP_REL(rel); | 1443 | JMP_REL(rel); |
1448 | break; | 1444 | break; |
1449 | } | 1445 | } |
1450 | case 0x9c: /* pushf */ | 1446 | case 0x9c: /* pushf */ |
1451 | c->src.val = (unsigned long) _eflags; | 1447 | c->src.val = (unsigned long) ctxt->eflags; |
1452 | emulate_push(ctxt); | 1448 | emulate_push(ctxt); |
1453 | break; | 1449 | break; |
1454 | case 0x9d: /* popf */ | 1450 | case 0x9d: /* popf */ |
1455 | c->dst.ptr = (unsigned long *) &_eflags; | 1451 | c->dst.ptr = (unsigned long *) &ctxt->eflags; |
1456 | goto pop_instruction; | 1452 | goto pop_instruction; |
1457 | case 0xc3: /* ret */ | 1453 | case 0xc3: /* ret */ |
1458 | c->dst.ptr = &c->eip; | 1454 | c->dst.ptr = &c->eip; |
@@ -1484,10 +1480,10 @@ special_insn: | |||
1484 | c->dst.bytes, ctxt->vcpu)) != 0) | 1480 | c->dst.bytes, ctxt->vcpu)) != 0) |
1485 | goto done; | 1481 | goto done; |
1486 | register_address_increment(c->regs[VCPU_REGS_RSI], | 1482 | register_address_increment(c->regs[VCPU_REGS_RSI], |
1487 | (_eflags & EFLG_DF) ? -c->dst.bytes | 1483 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
1488 | : c->dst.bytes); | 1484 | : c->dst.bytes); |
1489 | register_address_increment(c->regs[VCPU_REGS_RDI], | 1485 | register_address_increment(c->regs[VCPU_REGS_RDI], |
1490 | (_eflags & EFLG_DF) ? -c->dst.bytes | 1486 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
1491 | : c->dst.bytes); | 1487 | : c->dst.bytes); |
1492 | break; | 1488 | break; |
1493 | case 0xa6 ... 0xa7: /* cmps */ | 1489 | case 0xa6 ... 0xa7: /* cmps */ |
@@ -1499,7 +1495,7 @@ special_insn: | |||
1499 | c->dst.ptr = (unsigned long *)cr2; | 1495 | c->dst.ptr = (unsigned long *)cr2; |
1500 | c->dst.val = c->regs[VCPU_REGS_RAX]; | 1496 | c->dst.val = c->regs[VCPU_REGS_RAX]; |
1501 | register_address_increment(c->regs[VCPU_REGS_RDI], | 1497 | register_address_increment(c->regs[VCPU_REGS_RDI], |
1502 | (_eflags & EFLG_DF) ? -c->dst.bytes | 1498 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
1503 | : c->dst.bytes); | 1499 | : c->dst.bytes); |
1504 | break; | 1500 | break; |
1505 | case 0xac ... 0xad: /* lods */ | 1501 | case 0xac ... 0xad: /* lods */ |
@@ -1511,7 +1507,7 @@ special_insn: | |||
1511 | ctxt->vcpu)) != 0) | 1507 | ctxt->vcpu)) != 0) |
1512 | goto done; | 1508 | goto done; |
1513 | register_address_increment(c->regs[VCPU_REGS_RSI], | 1509 | register_address_increment(c->regs[VCPU_REGS_RSI], |
1514 | (_eflags & EFLG_DF) ? -c->dst.bytes | 1510 | (ctxt->eflags & EFLG_DF) ? -c->dst.bytes |
1515 | : c->dst.bytes); | 1511 | : c->dst.bytes); |
1516 | break; | 1512 | break; |
1517 | case 0xae ... 0xaf: /* scas */ | 1513 | case 0xae ... 0xaf: /* scas */ |
@@ -1599,7 +1595,8 @@ twobyte_insn: | |||
1599 | case 6: /* lmsw */ | 1595 | case 6: /* lmsw */ |
1600 | if (c->modrm_mod != 3) | 1596 | if (c->modrm_mod != 3) |
1601 | goto cannot_emulate; | 1597 | goto cannot_emulate; |
1602 | realmode_lmsw(ctxt->vcpu, (u16)c->modrm_val, &_eflags); | 1598 | realmode_lmsw(ctxt->vcpu, (u16)c->modrm_val, |
1599 | &ctxt->eflags); | ||
1603 | break; | 1600 | break; |
1604 | case 7: /* invlpg*/ | 1601 | case 7: /* invlpg*/ |
1605 | emulate_invlpg(ctxt->vcpu, cr2); | 1602 | emulate_invlpg(ctxt->vcpu, cr2); |
@@ -1630,29 +1627,29 @@ twobyte_insn: | |||
1630 | */ | 1627 | */ |
1631 | switch ((c->b & 15) >> 1) { | 1628 | switch ((c->b & 15) >> 1) { |
1632 | case 0: /* cmovo */ | 1629 | case 0: /* cmovo */ |
1633 | no_wb = (_eflags & EFLG_OF) ? 0 : 1; | 1630 | no_wb = (ctxt->eflags & EFLG_OF) ? 0 : 1; |
1634 | break; | 1631 | break; |
1635 | case 1: /* cmovb/cmovc/cmovnae */ | 1632 | case 1: /* cmovb/cmovc/cmovnae */ |
1636 | no_wb = (_eflags & EFLG_CF) ? 0 : 1; | 1633 | no_wb = (ctxt->eflags & EFLG_CF) ? 0 : 1; |
1637 | break; | 1634 | break; |
1638 | case 2: /* cmovz/cmove */ | 1635 | case 2: /* cmovz/cmove */ |
1639 | no_wb = (_eflags & EFLG_ZF) ? 0 : 1; | 1636 | no_wb = (ctxt->eflags & EFLG_ZF) ? 0 : 1; |
1640 | break; | 1637 | break; |
1641 | case 3: /* cmovbe/cmovna */ | 1638 | case 3: /* cmovbe/cmovna */ |
1642 | no_wb = (_eflags & (EFLG_CF | EFLG_ZF)) ? 0 : 1; | 1639 | no_wb = (ctxt->eflags & (EFLG_CF | EFLG_ZF)) ? 0 : 1; |
1643 | break; | 1640 | break; |
1644 | case 4: /* cmovs */ | 1641 | case 4: /* cmovs */ |
1645 | no_wb = (_eflags & EFLG_SF) ? 0 : 1; | 1642 | no_wb = (ctxt->eflags & EFLG_SF) ? 0 : 1; |
1646 | break; | 1643 | break; |
1647 | case 5: /* cmovp/cmovpe */ | 1644 | case 5: /* cmovp/cmovpe */ |
1648 | no_wb = (_eflags & EFLG_PF) ? 0 : 1; | 1645 | no_wb = (ctxt->eflags & EFLG_PF) ? 0 : 1; |
1649 | break; | 1646 | break; |
1650 | case 7: /* cmovle/cmovng */ | 1647 | case 7: /* cmovle/cmovng */ |
1651 | no_wb = (_eflags & EFLG_ZF) ? 0 : 1; | 1648 | no_wb = (ctxt->eflags & EFLG_ZF) ? 0 : 1; |
1652 | /* fall through */ | 1649 | /* fall through */ |
1653 | case 6: /* cmovl/cmovnge */ | 1650 | case 6: /* cmovl/cmovnge */ |
1654 | no_wb &= (!(_eflags & EFLG_SF) != | 1651 | no_wb &= (!(ctxt->eflags & EFLG_SF) != |
1655 | !(_eflags & EFLG_OF)) ? 0 : 1; | 1652 | !(ctxt->eflags & EFLG_OF)) ? 0 : 1; |
1656 | break; | 1653 | break; |
1657 | } | 1654 | } |
1658 | /* Odd cmov opcodes (lsb == 1) have inverted sense. */ | 1655 | /* Odd cmov opcodes (lsb == 1) have inverted sense. */ |
@@ -1662,13 +1659,13 @@ twobyte_insn: | |||
1662 | bt: /* bt */ | 1659 | bt: /* bt */ |
1663 | /* only subword offset */ | 1660 | /* only subword offset */ |
1664 | c->src.val &= (c->dst.bytes << 3) - 1; | 1661 | c->src.val &= (c->dst.bytes << 3) - 1; |
1665 | emulate_2op_SrcV_nobyte("bt", c->src, c->dst, _eflags); | 1662 | emulate_2op_SrcV_nobyte("bt", c->src, c->dst, ctxt->eflags); |
1666 | break; | 1663 | break; |
1667 | case 0xab: | 1664 | case 0xab: |
1668 | bts: /* bts */ | 1665 | bts: /* bts */ |
1669 | /* only subword offset */ | 1666 | /* only subword offset */ |
1670 | c->src.val &= (c->dst.bytes << 3) - 1; | 1667 | c->src.val &= (c->dst.bytes << 3) - 1; |
1671 | emulate_2op_SrcV_nobyte("bts", c->src, c->dst, _eflags); | 1668 | emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags); |
1672 | break; | 1669 | break; |
1673 | case 0xb0 ... 0xb1: /* cmpxchg */ | 1670 | case 0xb0 ... 0xb1: /* cmpxchg */ |
1674 | /* | 1671 | /* |
@@ -1677,8 +1674,8 @@ twobyte_insn: | |||
1677 | */ | 1674 | */ |
1678 | c->src.orig_val = c->src.val; | 1675 | c->src.orig_val = c->src.val; |
1679 | c->src.val = c->regs[VCPU_REGS_RAX]; | 1676 | c->src.val = c->regs[VCPU_REGS_RAX]; |
1680 | emulate_2op_SrcV("cmp", c->src, c->dst, _eflags); | 1677 | emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags); |
1681 | if (_eflags & EFLG_ZF) { | 1678 | if (ctxt->eflags & EFLG_ZF) { |
1682 | /* Success: write back to memory. */ | 1679 | /* Success: write back to memory. */ |
1683 | c->dst.val = c->src.orig_val; | 1680 | c->dst.val = c->src.orig_val; |
1684 | } else { | 1681 | } else { |
@@ -1691,7 +1688,7 @@ twobyte_insn: | |||
1691 | btr: /* btr */ | 1688 | btr: /* btr */ |
1692 | /* only subword offset */ | 1689 | /* only subword offset */ |
1693 | c->src.val &= (c->dst.bytes << 3) - 1; | 1690 | c->src.val &= (c->dst.bytes << 3) - 1; |
1694 | emulate_2op_SrcV_nobyte("btr", c->src, c->dst, _eflags); | 1691 | emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags); |
1695 | break; | 1692 | break; |
1696 | case 0xb6 ... 0xb7: /* movzx */ | 1693 | case 0xb6 ... 0xb7: /* movzx */ |
1697 | c->dst.bytes = c->op_bytes; | 1694 | c->dst.bytes = c->op_bytes; |
@@ -1714,7 +1711,7 @@ twobyte_insn: | |||
1714 | btc: /* btc */ | 1711 | btc: /* btc */ |
1715 | /* only subword offset */ | 1712 | /* only subword offset */ |
1716 | c->src.val &= (c->dst.bytes << 3) - 1; | 1713 | c->src.val &= (c->dst.bytes << 3) - 1; |
1717 | emulate_2op_SrcV_nobyte("btc", c->src, c->dst, _eflags); | 1714 | emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags); |
1718 | break; | 1715 | break; |
1719 | case 0xbe ... 0xbf: /* movsx */ | 1716 | case 0xbe ... 0xbf: /* movsx */ |
1720 | c->dst.bytes = c->op_bytes; | 1717 | c->dst.bytes = c->op_bytes; |
@@ -1753,7 +1750,7 @@ twobyte_special_insn: | |||
1753 | if (c->modrm_mod != 3) | 1750 | if (c->modrm_mod != 3) |
1754 | goto cannot_emulate; | 1751 | goto cannot_emulate; |
1755 | realmode_set_cr(ctxt->vcpu, | 1752 | realmode_set_cr(ctxt->vcpu, |
1756 | c->modrm_reg, c->modrm_val, &_eflags); | 1753 | c->modrm_reg, c->modrm_val, &ctxt->eflags); |
1757 | break; | 1754 | break; |
1758 | case 0x30: | 1755 | case 0x30: |
1759 | /* wrmsr */ | 1756 | /* wrmsr */ |
@@ -1795,12 +1792,12 @@ twobyte_special_insn: | |||
1795 | DPRINTF("jnz: Invalid op_bytes\n"); | 1792 | DPRINTF("jnz: Invalid op_bytes\n"); |
1796 | goto cannot_emulate; | 1793 | goto cannot_emulate; |
1797 | } | 1794 | } |
1798 | if (test_cc(c->b, _eflags)) | 1795 | if (test_cc(c->b, ctxt->eflags)) |
1799 | JMP_REL(rel); | 1796 | JMP_REL(rel); |
1800 | break; | 1797 | break; |
1801 | } | 1798 | } |
1802 | case 0xc7: /* Grp9 (cmpxchg8b) */ | 1799 | case 0xc7: /* Grp9 (cmpxchg8b) */ |
1803 | rc = emulate_grp9(ctxt, ops, &_eflags, cr2); | 1800 | rc = emulate_grp9(ctxt, ops, cr2); |
1804 | if (rc != 0) | 1801 | if (rc != 0) |
1805 | goto done; | 1802 | goto done; |
1806 | break; | 1803 | break; |