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 | |
| 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>
| -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; |
