diff options
author | Avi Kivity <avi@qumranet.com> | 2007-04-22 08:28:19 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-05-03 03:52:31 -0400 |
commit | 4c690a1e8667a84b61a6114a4ad293681f32cb11 (patch) | |
tree | ed5ffaedc83068a7cf791530a2f54483107f3d21 /drivers/kvm/x86_emulate.c | |
parent | 1165f5fec18c077bdba88e7125fd41f8e3617cb4 (diff) |
KVM: Allow passing 64-bit values to the emulated read/write API
This simplifies the API somewhat (by eliminating the special-case
cmpxchg8b on i386).
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r-- | drivers/kvm/x86_emulate.c | 46 |
1 files changed, 9 insertions, 37 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index bcf872bdaf74..7ade09086aa5 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c | |||
@@ -1045,7 +1045,7 @@ done_prefixes: | |||
1045 | if ((rc = ops->write_std( | 1045 | if ((rc = ops->write_std( |
1046 | register_address(ctxt->ss_base, | 1046 | register_address(ctxt->ss_base, |
1047 | _regs[VCPU_REGS_RSP]), | 1047 | _regs[VCPU_REGS_RSP]), |
1048 | dst.val, dst.bytes, ctxt)) != 0) | 1048 | &dst.val, dst.bytes, ctxt)) != 0) |
1049 | goto done; | 1049 | goto done; |
1050 | dst.val = dst.orig_val; /* skanky: disable writeback */ | 1050 | dst.val = dst.orig_val; /* skanky: disable writeback */ |
1051 | break; | 1051 | break; |
@@ -1078,12 +1078,12 @@ writeback: | |||
1078 | case OP_MEM: | 1078 | case OP_MEM: |
1079 | if (lock_prefix) | 1079 | if (lock_prefix) |
1080 | rc = ops->cmpxchg_emulated((unsigned long)dst. | 1080 | rc = ops->cmpxchg_emulated((unsigned long)dst. |
1081 | ptr, dst.orig_val, | 1081 | ptr, &dst.orig_val, |
1082 | dst.val, dst.bytes, | 1082 | &dst.val, dst.bytes, |
1083 | ctxt); | 1083 | ctxt); |
1084 | else | 1084 | else |
1085 | rc = ops->write_emulated((unsigned long)dst.ptr, | 1085 | rc = ops->write_emulated((unsigned long)dst.ptr, |
1086 | dst.val, dst.bytes, | 1086 | &dst.val, dst.bytes, |
1087 | ctxt); | 1087 | ctxt); |
1088 | if (rc != 0) | 1088 | if (rc != 0) |
1089 | goto done; | 1089 | goto done; |
@@ -1321,36 +1321,8 @@ twobyte_special_insn: | |||
1321 | realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags); | 1321 | realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags); |
1322 | break; | 1322 | break; |
1323 | case 0xc7: /* Grp9 (cmpxchg8b) */ | 1323 | case 0xc7: /* Grp9 (cmpxchg8b) */ |
1324 | #if defined(__i386__) | ||
1325 | { | 1324 | { |
1326 | unsigned long old_lo, old_hi; | 1325 | u64 old, new; |
1327 | if (((rc = ops->read_emulated(cr2 + 0, &old_lo, 4, | ||
1328 | ctxt)) != 0) | ||
1329 | || ((rc = ops->read_emulated(cr2 + 4, &old_hi, 4, | ||
1330 | ctxt)) != 0)) | ||
1331 | goto done; | ||
1332 | if ((old_lo != _regs[VCPU_REGS_RAX]) | ||
1333 | || (old_hi != _regs[VCPU_REGS_RDX])) { | ||
1334 | _regs[VCPU_REGS_RAX] = old_lo; | ||
1335 | _regs[VCPU_REGS_RDX] = old_hi; | ||
1336 | _eflags &= ~EFLG_ZF; | ||
1337 | } else if (ops->cmpxchg8b_emulated == NULL) { | ||
1338 | rc = X86EMUL_UNHANDLEABLE; | ||
1339 | goto done; | ||
1340 | } else { | ||
1341 | if ((rc = ops->cmpxchg8b_emulated(cr2, old_lo, | ||
1342 | old_hi, | ||
1343 | _regs[VCPU_REGS_RBX], | ||
1344 | _regs[VCPU_REGS_RCX], | ||
1345 | ctxt)) != 0) | ||
1346 | goto done; | ||
1347 | _eflags |= EFLG_ZF; | ||
1348 | } | ||
1349 | break; | ||
1350 | } | ||
1351 | #elif defined(CONFIG_X86_64) | ||
1352 | { | ||
1353 | unsigned long old, new; | ||
1354 | if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0) | 1326 | if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0) |
1355 | goto done; | 1327 | goto done; |
1356 | if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) || | 1328 | if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) || |
@@ -1359,15 +1331,15 @@ twobyte_special_insn: | |||
1359 | _regs[VCPU_REGS_RDX] = (u32) (old >> 32); | 1331 | _regs[VCPU_REGS_RDX] = (u32) (old >> 32); |
1360 | _eflags &= ~EFLG_ZF; | 1332 | _eflags &= ~EFLG_ZF; |
1361 | } else { | 1333 | } else { |
1362 | new = (_regs[VCPU_REGS_RCX] << 32) | (u32) _regs[VCPU_REGS_RBX]; | 1334 | new = ((u64)_regs[VCPU_REGS_RCX] << 32) |
1363 | if ((rc = ops->cmpxchg_emulated(cr2, old, | 1335 | | (u32) _regs[VCPU_REGS_RBX]; |
1364 | new, 8, ctxt)) != 0) | 1336 | if ((rc = ops->cmpxchg_emulated(cr2, &old, |
1337 | &new, 8, ctxt)) != 0) | ||
1365 | goto done; | 1338 | goto done; |
1366 | _eflags |= EFLG_ZF; | 1339 | _eflags |= EFLG_ZF; |
1367 | } | 1340 | } |
1368 | break; | 1341 | break; |
1369 | } | 1342 | } |
1370 | #endif | ||
1371 | } | 1343 | } |
1372 | goto writeback; | 1344 | goto writeback; |
1373 | 1345 | ||