aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86_emulate.c
diff options
context:
space:
mode:
authorLaurent Vivier <Laurent.Vivier@bull.net>2007-09-24 05:10:54 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:52:48 -0500
commit8cdbd2c9bf3108c41563eef586f22fa8b5174de0 (patch)
treed64daf3bf5b9a85c667c016399352151726ba723 /drivers/kvm/x86_emulate.c
parent217648638ccb62dfeea5ac5fe768539cdee61ed0 (diff)
KVM: x86 emulator: split some decoding into functions for readability
To improve readability, move push, writeback, and grp 1a/2/3/4/5/9 emulation parts into functions. 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.c451
1 files changed, 266 insertions, 185 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index dc9d2a870fbc..a15609279283 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -907,6 +907,244 @@ done:
907 return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; 907 return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
908} 908}
909 909
910static inline void emulate_push(struct x86_emulate_ctxt *ctxt)
911{
912 struct decode_cache *c = &ctxt->decode;
913
914 c->dst.type = OP_MEM;
915 c->dst.bytes = c->op_bytes;
916 c->dst.val = c->src.val;
917 register_address_increment(c->regs[VCPU_REGS_RSP], -c->op_bytes);
918 c->dst.ptr = (void *) register_address(ctxt->ss_base,
919 c->regs[VCPU_REGS_RSP]);
920}
921
922static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
923 struct x86_emulate_ops *ops)
924{
925 struct decode_cache *c = &ctxt->decode;
926 int rc;
927
928 /* 64-bit mode: POP always pops a 64-bit operand. */
929
930 if (ctxt->mode == X86EMUL_MODE_PROT64)
931 c->dst.bytes = 8;
932
933 rc = ops->read_std(register_address(ctxt->ss_base,
934 c->regs[VCPU_REGS_RSP]),
935 &c->dst.val, c->dst.bytes, ctxt->vcpu);
936 if (rc != 0)
937 return rc;
938
939 register_address_increment(c->regs[VCPU_REGS_RSP], c->dst.bytes);
940
941 return 0;
942}
943
944static inline void emulate_grp2(struct decode_cache *c, unsigned long *_eflags)
945{
946 switch (c->modrm_reg) {
947 case 0: /* rol */
948 emulate_2op_SrcB("rol", c->src, c->dst, *_eflags);
949 break;
950 case 1: /* ror */
951 emulate_2op_SrcB("ror", c->src, c->dst, *_eflags);
952 break;
953 case 2: /* rcl */
954 emulate_2op_SrcB("rcl", c->src, c->dst, *_eflags);
955 break;
956 case 3: /* rcr */
957 emulate_2op_SrcB("rcr", c->src, c->dst, *_eflags);
958 break;
959 case 4: /* sal/shl */
960 case 6: /* sal/shl */
961 emulate_2op_SrcB("sal", c->src, c->dst, *_eflags);
962 break;
963 case 5: /* shr */
964 emulate_2op_SrcB("shr", c->src, c->dst, *_eflags);
965 break;
966 case 7: /* sar */
967 emulate_2op_SrcB("sar", c->src, c->dst, *_eflags);
968 break;
969 }
970}
971
972static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
973 struct x86_emulate_ops *ops,
974 unsigned long *_eflags)
975{
976 struct decode_cache *c = &ctxt->decode;
977 int rc = 0;
978
979 switch (c->modrm_reg) {
980 case 0 ... 1: /* test */
981 /*
982 * Special case in Grp3: test has an immediate
983 * source operand.
984 */
985 c->src.type = OP_IMM;
986 c->src.ptr = (unsigned long *)c->eip;
987 c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
988 if (c->src.bytes == 8)
989 c->src.bytes = 4;
990 switch (c->src.bytes) {
991 case 1:
992 c->src.val = insn_fetch(s8, 1, c->eip);
993 break;
994 case 2:
995 c->src.val = insn_fetch(s16, 2, c->eip);
996 break;
997 case 4:
998 c->src.val = insn_fetch(s32, 4, c->eip);
999 break;
1000 }
1001 emulate_2op_SrcV("test", c->src, c->dst, *_eflags);
1002 break;
1003 case 2: /* not */
1004 c->dst.val = ~c->dst.val;
1005 break;
1006 case 3: /* neg */
1007 emulate_1op("neg", c->dst, *_eflags);
1008 break;
1009 default:
1010 DPRINTF("Cannot emulate %02x\n", c->b);
1011 rc = X86EMUL_UNHANDLEABLE;
1012 break;
1013 }
1014done:
1015 return rc;
1016}
1017
1018static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
1019 struct x86_emulate_ops *ops,
1020 unsigned long *_eflags,
1021 int *no_wb)
1022{
1023 struct decode_cache *c = &ctxt->decode;
1024 int rc;
1025
1026 switch (c->modrm_reg) {
1027 case 0: /* inc */
1028 emulate_1op("inc", c->dst, *_eflags);
1029 break;
1030 case 1: /* dec */
1031 emulate_1op("dec", c->dst, *_eflags);
1032 break;
1033 case 4: /* jmp abs */
1034 if (c->b == 0xff)
1035 c->eip = c->dst.val;
1036 else {
1037 DPRINTF("Cannot emulate %02x\n", c->b);
1038 return X86EMUL_UNHANDLEABLE;
1039 }
1040 break;
1041 case 6: /* push */
1042
1043 /* 64-bit mode: PUSH always pushes a 64-bit operand. */
1044
1045 if (ctxt->mode == X86EMUL_MODE_PROT64) {
1046 c->dst.bytes = 8;
1047 rc = ops->read_std((unsigned long)c->dst.ptr,
1048 &c->dst.val, 8, ctxt->vcpu);
1049 if (rc != 0)
1050 return rc;
1051 }
1052 register_address_increment(c->regs[VCPU_REGS_RSP],
1053 -c->dst.bytes);
1054 rc = ops->write_emulated(register_address(ctxt->ss_base,
1055 c->regs[VCPU_REGS_RSP]), &c->dst.val,
1056 c->dst.bytes, ctxt->vcpu);
1057 if (rc != 0)
1058 return rc;
1059 *no_wb = 1;
1060 break;
1061 default:
1062 DPRINTF("Cannot emulate %02x\n", c->b);
1063 return X86EMUL_UNHANDLEABLE;
1064 }
1065 return 0;
1066}
1067
1068static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
1069 struct x86_emulate_ops *ops,
1070 unsigned long *_eflags,
1071 unsigned long cr2)
1072{
1073 struct decode_cache *c = &ctxt->decode;
1074 u64 old, new;
1075 int rc;
1076
1077 rc = ops->read_emulated(cr2, &old, 8, ctxt->vcpu);
1078 if (rc != 0)
1079 return rc;
1080
1081 if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) ||
1082 ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) {
1083
1084 c->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
1085 c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
1086 *_eflags &= ~EFLG_ZF;
1087
1088 } else {
1089 new = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
1090 (u32) c->regs[VCPU_REGS_RBX];
1091
1092 rc = ops->cmpxchg_emulated(cr2, &old, &new, 8, ctxt->vcpu);
1093 if (rc != 0)
1094 return rc;
1095 *_eflags |= EFLG_ZF;
1096 }
1097 return 0;
1098}
1099
1100static inline int writeback(struct x86_emulate_ctxt *ctxt,
1101 struct x86_emulate_ops *ops)
1102{
1103 int rc;
1104 struct decode_cache *c = &ctxt->decode;
1105
1106 switch (c->dst.type) {
1107 case OP_REG:
1108 /* The 4-byte case *is* correct:
1109 * in 64-bit mode we zero-extend.
1110 */
1111 switch (c->dst.bytes) {
1112 case 1:
1113 *(u8 *)c->dst.ptr = (u8)c->dst.val;
1114 break;
1115 case 2:
1116 *(u16 *)c->dst.ptr = (u16)c->dst.val;
1117 break;
1118 case 4:
1119 *c->dst.ptr = (u32)c->dst.val;
1120 break; /* 64b: zero-ext */
1121 case 8:
1122 *c->dst.ptr = c->dst.val;
1123 break;
1124 }
1125 break;
1126 case OP_MEM:
1127 if (c->lock_prefix)
1128 rc = ops->cmpxchg_emulated(
1129 (unsigned long)c->dst.ptr,
1130 &c->dst.orig_val,
1131 &c->dst.val,
1132 c->dst.bytes,
1133 ctxt->vcpu);
1134 else
1135 rc = ops->write_emulated(
1136 (unsigned long)c->dst.ptr,
1137 &c->dst.val,
1138 c->dst.bytes,
1139 ctxt->vcpu);
1140 if (rc != 0)
1141 return rc;
1142 default:
1143 break;
1144 }
1145 return 0;
1146}
1147
910int 1148int
911x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) 1149x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
912{ 1150{
@@ -1042,7 +1280,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1042 } 1280 }
1043 break; 1281 break;
1044 case 0x84 ... 0x85: 1282 case 0x84 ... 0x85:
1045 test: /* test */
1046 emulate_2op_SrcV("test", c->src, c->dst, _eflags); 1283 emulate_2op_SrcV("test", c->src, c->dst, _eflags);
1047 break; 1284 break;
1048 case 0x86 ... 0x87: /* xchg */ 1285 case 0x86 ... 0x87: /* xchg */
@@ -1074,18 +1311,9 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1074 c->dst.val = c->modrm_val; 1311 c->dst.val = c->modrm_val;
1075 break; 1312 break;
1076 case 0x8f: /* pop (sole member of Grp1a) */ 1313 case 0x8f: /* pop (sole member of Grp1a) */
1077 /* 64-bit mode: POP always pops a 64-bit operand. */ 1314 rc = emulate_grp1a(ctxt, ops);
1078 if (ctxt->mode == X86EMUL_MODE_PROT64) 1315 if (rc != 0)
1079 c->dst.bytes = 8;
1080 if ((rc = ops->read_std(register_address(
1081 ctxt->ss_base,
1082 c->regs[VCPU_REGS_RSP]),
1083 &c->dst.val,
1084 c->dst.bytes,
1085 ctxt->vcpu)) != 0)
1086 goto done; 1316 goto done;
1087 register_address_increment(c->regs[VCPU_REGS_RSP],
1088 c->dst.bytes);
1089 break; 1317 break;
1090 case 0xa0 ... 0xa1: /* mov */ 1318 case 0xa0 ... 0xa1: /* mov */
1091 c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; 1319 c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
@@ -1099,31 +1327,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1099 c->eip += c->ad_bytes; 1327 c->eip += c->ad_bytes;
1100 break; 1328 break;
1101 case 0xc0 ... 0xc1: 1329 case 0xc0 ... 0xc1:
1102 grp2: /* Grp2 */ 1330 emulate_grp2(c, &_eflags);
1103 switch (c->modrm_reg) {
1104 case 0: /* rol */
1105 emulate_2op_SrcB("rol", c->src, c->dst, _eflags);
1106 break;
1107 case 1: /* ror */
1108 emulate_2op_SrcB("ror", c->src, c->dst, _eflags);
1109 break;
1110 case 2: /* rcl */
1111 emulate_2op_SrcB("rcl", c->src, c->dst, _eflags);
1112 break;
1113 case 3: /* rcr */
1114 emulate_2op_SrcB("rcr", c->src, c->dst, _eflags);
1115 break;
1116 case 4: /* sal/shl */
1117 case 6: /* sal/shl */
1118 emulate_2op_SrcB("sal", c->src, c->dst, _eflags);
1119 break;
1120 case 5: /* shr */
1121 emulate_2op_SrcB("shr", c->src, c->dst, _eflags);
1122 break;
1123 case 7: /* sar */
1124 emulate_2op_SrcB("sar", c->src, c->dst, _eflags);
1125 break;
1126 }
1127 break; 1331 break;
1128 case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ 1332 case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
1129 mov: 1333 mov:
@@ -1131,126 +1335,29 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
1131 break; 1335 break;
1132 case 0xd0 ... 0xd1: /* Grp2 */ 1336 case 0xd0 ... 0xd1: /* Grp2 */
1133 c->src.val = 1; 1337 c->src.val = 1;
1134 goto grp2; 1338 emulate_grp2(c, &_eflags);
1339 break;
1135 case 0xd2 ... 0xd3: /* Grp2 */ 1340 case 0xd2 ... 0xd3: /* Grp2 */
1136 c->src.val = c->regs[VCPU_REGS_RCX]; 1341 c->src.val = c->regs[VCPU_REGS_RCX];
1137 goto grp2; 1342 emulate_grp2(c, &_eflags);
1343 break;
1138 case 0xf6 ... 0xf7: /* Grp3 */ 1344 case 0xf6 ... 0xf7: /* Grp3 */
1139 switch (c->modrm_reg) { 1345 rc = emulate_grp3(ctxt, ops, &_eflags);
1140 case 0 ... 1: /* test */ 1346 if (rc != 0)
1141 /* 1347 goto done;
1142 * Special case in Grp3: test has an immediate
1143 * source operand.
1144 */
1145 c->src.type = OP_IMM;
1146 c->src.ptr = (unsigned long *)c->eip;
1147 c->src.bytes = (c->d & ByteOp) ? 1 :
1148 c->op_bytes;
1149 if (c->src.bytes == 8)
1150 c->src.bytes = 4;
1151 switch (c->src.bytes) {
1152 case 1:
1153 c->src.val = insn_fetch(s8, 1, c->eip);
1154 break;
1155 case 2:
1156 c->src.val = insn_fetch(s16, 2, c->eip);
1157 break;
1158 case 4:
1159 c->src.val = insn_fetch(s32, 4, c->eip);
1160 break;
1161 }
1162 goto test;
1163 case 2: /* not */
1164 c->dst.val = ~c->dst.val;
1165 break;
1166 case 3: /* neg */
1167 emulate_1op("neg", c->dst, _eflags);
1168 break;
1169 default:
1170 goto cannot_emulate;
1171 }
1172 break; 1348 break;
1173 case 0xfe ... 0xff: /* Grp4/Grp5 */ 1349 case 0xfe ... 0xff: /* Grp4/Grp5 */
1174 switch (c->modrm_reg) { 1350 rc = emulate_grp45(ctxt, ops, &_eflags, &no_wb);
1175 case 0: /* inc */ 1351 if (rc != 0)
1176 emulate_1op("inc", c->dst, _eflags); 1352 goto done;
1177 break;
1178 case 1: /* dec */
1179 emulate_1op("dec", c->dst, _eflags);
1180 break;
1181 case 4: /* jmp abs */
1182 if (c->b == 0xff)
1183 c->eip = c->dst.val;
1184 else
1185 goto cannot_emulate;
1186 break;
1187 case 6: /* push */
1188 /* 64-bit mode: PUSH always pushes a 64-bit operand. */
1189 if (ctxt->mode == X86EMUL_MODE_PROT64) {
1190 c->dst.bytes = 8;
1191 if ((rc = ops->read_std(
1192 (unsigned long)c->dst.ptr,
1193 &c->dst.val, 8,
1194 ctxt->vcpu)) != 0)
1195 goto done;
1196 }
1197 register_address_increment(c->regs[VCPU_REGS_RSP],
1198 -c->dst.bytes);
1199 if ((rc = ops->write_emulated(
1200 register_address(ctxt->ss_base,
1201 c->regs[VCPU_REGS_RSP]),
1202 &c->dst.val,
1203 c->dst.bytes, ctxt->vcpu)) != 0)
1204 goto done;
1205 no_wb = 1;
1206 break;
1207 default:
1208 goto cannot_emulate;
1209 }
1210 break; 1353 break;
1211 } 1354 }
1212 1355
1213writeback: 1356writeback:
1214 if (!no_wb) { 1357 if (!no_wb) {
1215 switch (c->dst.type) { 1358 rc = writeback(ctxt, ops);
1216 case OP_REG: 1359 if (rc != 0)
1217 /* The 4-byte case *is* correct: 1360 goto done;
1218 * in 64-bit mode we zero-extend.
1219 */
1220 switch (c->dst.bytes) {
1221 case 1:
1222 *(u8 *)c->dst.ptr = (u8)c->dst.val;
1223 break;
1224 case 2:
1225 *(u16 *)c->dst.ptr = (u16)c->dst.val;
1226 break;
1227 case 4:
1228 *c->dst.ptr = (u32)c->dst.val;
1229 break; /* 64b: zero-ext */
1230 case 8:
1231 *c->dst.ptr = c->dst.val;
1232 break;
1233 }
1234 break;
1235 case OP_MEM:
1236 if (c->lock_prefix)
1237 rc = ops->cmpxchg_emulated(
1238 (unsigned long)c->dst.ptr,
1239 &c->dst.orig_val,
1240 &c->dst.val,
1241 c->dst.bytes,
1242 ctxt->vcpu);
1243 else
1244 rc = ops->write_emulated(
1245 (unsigned long)c->dst.ptr,
1246 &c->dst.val,
1247 c->dst.bytes,
1248 ctxt->vcpu);
1249 if (rc != 0)
1250 goto done;
1251 default:
1252 break;
1253 }
1254 } 1361 }
1255 1362
1256 /* Commit shadow register state. */ 1363 /* Commit shadow register state. */
@@ -1283,8 +1390,7 @@ special_insn:
1283 ctxt->ss_base, c->regs[VCPU_REGS_RSP]); 1390 ctxt->ss_base, c->regs[VCPU_REGS_RSP]);
1284 break; 1391 break;
1285 case 0x58 ... 0x5f: /* pop reg */ 1392 case 0x58 ... 0x5f: /* pop reg */
1286 c->dst.ptr = 1393 c->dst.ptr = (unsigned long *)&c->regs[c->b & 0x7];
1287 (unsigned long *)&c->regs[c->b & 0x7];
1288 pop_instruction: 1394 pop_instruction:
1289 if ((rc = ops->read_std(register_address(ctxt->ss_base, 1395 if ((rc = ops->read_std(register_address(ctxt->ss_base,
1290 c->regs[VCPU_REGS_RSP]), c->dst.ptr, 1396 c->regs[VCPU_REGS_RSP]), c->dst.ptr,
@@ -1298,14 +1404,7 @@ special_insn:
1298 case 0x6a: /* push imm8 */ 1404 case 0x6a: /* push imm8 */
1299 c->src.val = 0L; 1405 c->src.val = 0L;
1300 c->src.val = insn_fetch(s8, 1, c->eip); 1406 c->src.val = insn_fetch(s8, 1, c->eip);
1301push: 1407 emulate_push(ctxt);
1302 c->dst.type = OP_MEM;
1303 c->dst.bytes = c->op_bytes;
1304 c->dst.val = c->src.val;
1305 register_address_increment(c->regs[VCPU_REGS_RSP],
1306 -c->op_bytes);
1307 c->dst.ptr = (void *) register_address(ctxt->ss_base,
1308 c->regs[VCPU_REGS_RSP]);
1309 break; 1408 break;
1310 case 0x6c: /* insb */ 1409 case 0x6c: /* insb */
1311 case 0x6d: /* insw/insd */ 1410 case 0x6d: /* insw/insd */
@@ -1350,7 +1449,8 @@ push:
1350 } 1449 }
1351 case 0x9c: /* pushf */ 1450 case 0x9c: /* pushf */
1352 c->src.val = (unsigned long) _eflags; 1451 c->src.val = (unsigned long) _eflags;
1353 goto push; 1452 emulate_push(ctxt);
1453 break;
1354 case 0x9d: /* popf */ 1454 case 0x9d: /* popf */
1355 c->dst.ptr = (unsigned long *) &_eflags; 1455 c->dst.ptr = (unsigned long *) &_eflags;
1356 goto pop_instruction; 1456 goto pop_instruction;
@@ -1436,7 +1536,8 @@ push:
1436 c->src.val = (unsigned long) c->eip; 1536 c->src.val = (unsigned long) c->eip;
1437 JMP_REL(rel); 1537 JMP_REL(rel);
1438 c->op_bytes = c->ad_bytes; 1538 c->op_bytes = c->ad_bytes;
1439 goto push; 1539 emulate_push(ctxt);
1540 break;
1440 } 1541 }
1441 case 0xe9: /* jmp rel */ 1542 case 0xe9: /* jmp rel */
1442 case 0xeb: /* jmp rel short */ 1543 case 0xeb: /* jmp rel short */
@@ -1511,8 +1612,7 @@ twobyte_insn:
1511 no_wb = 1; 1612 no_wb = 1;
1512 if (c->modrm_mod != 3) 1613 if (c->modrm_mod != 3)
1513 goto cannot_emulate; 1614 goto cannot_emulate;
1514 rc = emulator_get_dr(ctxt, c->modrm_reg, 1615 rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]);
1515 &c->regs[c->modrm_rm]);
1516 break; 1616 break;
1517 case 0x23: /* mov from reg to dr */ 1617 case 0x23: /* mov from reg to dr */
1518 no_wb = 1; 1618 no_wb = 1;
@@ -1668,8 +1768,7 @@ twobyte_special_insn:
1668 break; 1768 break;
1669 case 0x32: 1769 case 0x32:
1670 /* rdmsr */ 1770 /* rdmsr */
1671 rc = kvm_get_msr(ctxt->vcpu, 1771 rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data);
1672 c->regs[VCPU_REGS_RCX], &msr_data);
1673 if (rc) { 1772 if (rc) {
1674 kvm_x86_ops->inject_gp(ctxt->vcpu, 0); 1773 kvm_x86_ops->inject_gp(ctxt->vcpu, 0);
1675 c->eip = ctxt->vcpu->rip; 1774 c->eip = ctxt->vcpu->rip;
@@ -1701,28 +1800,10 @@ twobyte_special_insn:
1701 break; 1800 break;
1702 } 1801 }
1703 case 0xc7: /* Grp9 (cmpxchg8b) */ 1802 case 0xc7: /* Grp9 (cmpxchg8b) */
1704 { 1803 rc = emulate_grp9(ctxt, ops, &_eflags, cr2);
1705 u64 old, new; 1804 if (rc != 0)
1706 if ((rc = ops->read_emulated(cr2, &old, 8, ctxt->vcpu)) 1805 goto done;
1707 != 0) 1806 break;
1708 goto done;
1709 if (((u32) (old >> 0) !=
1710 (u32) c->regs[VCPU_REGS_RAX]) ||
1711 ((u32) (old >> 32) !=
1712 (u32) c->regs[VCPU_REGS_RDX])) {
1713 c->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
1714 c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
1715 _eflags &= ~EFLG_ZF;
1716 } else {
1717 new = ((u64)c->regs[VCPU_REGS_RCX] << 32)
1718 | (u32) c->regs[VCPU_REGS_RBX];
1719 if ((rc = ops->cmpxchg_emulated(cr2, &old,
1720 &new, 8, ctxt->vcpu)) != 0)
1721 goto done;
1722 _eflags |= EFLG_ZF;
1723 }
1724 break;
1725 }
1726 } 1807 }
1727 goto writeback; 1808 goto writeback;
1728 1809