aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86_emulate.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-06 16:21:18 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-06 16:21:18 -0400
commit6de410c2b0cc055ae9ee640c84331f6a70878d9b (patch)
tree49dfc7df2f1977c2d665c99266ded92afc98734b /drivers/kvm/x86_emulate.c
parentc6799ade4ae04b53a5f677e5289116155ff01574 (diff)
parent2ff81f70b56dc1cdd3bf2f08414608069db6ef1a (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm: (66 commits) KVM: Remove unused 'instruction_length' KVM: Don't require explicit indication of completion of mmio or pio KVM: Remove extraneous guest entry on mmio read KVM: SVM: Only save/restore MSRs when needed KVM: fix an if() condition KVM: VMX: Add lazy FPU support for VT KVM: VMX: Properly shadow the CR0 register in the vcpu struct KVM: Don't complain about cpu erratum AA15 KVM: Lazy FPU support for SVM KVM: Allow passing 64-bit values to the emulated read/write API KVM: Per-vcpu statistics KVM: VMX: Avoid unnecessary vcpu_load()/vcpu_put() cycles KVM: MMU: Avoid heavy ASSERT at non debug mode. KVM: VMX: Only save/restore MSR_K6_STAR if necessary KVM: Fold drivers/kvm/kvm_vmx.h into drivers/kvm/vmx.c KVM: VMX: Don't switch 64-bit msrs for 32-bit guests KVM: VMX: Reduce unnecessary saving of host msrs KVM: Handle guest page faults when emulating mmio KVM: SVM: Report hardware exit reason to userspace instead of dmesg KVM: Retry sleeping allocation if atomic allocation fails ...
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r--drivers/kvm/x86_emulate.c51
1 files changed, 12 insertions, 39 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 7513cddb929f..7ade09086aa5 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -833,8 +833,9 @@ done_prefixes:
833 dst.ptr = (unsigned long *)cr2; 833 dst.ptr = (unsigned long *)cr2;
834 dst.bytes = (d & ByteOp) ? 1 : op_bytes; 834 dst.bytes = (d & ByteOp) ? 1 : op_bytes;
835 if (d & BitOp) { 835 if (d & BitOp) {
836 dst.ptr += src.val / BITS_PER_LONG; 836 unsigned long mask = ~(dst.bytes * 8 - 1);
837 dst.bytes = sizeof(long); 837
838 dst.ptr = (void *)dst.ptr + (src.val & mask) / 8;
838 } 839 }
839 if (!(d & Mov) && /* optimisation - avoid slow emulated read */ 840 if (!(d & Mov) && /* optimisation - avoid slow emulated read */
840 ((rc = ops->read_emulated((unsigned long)dst.ptr, 841 ((rc = ops->read_emulated((unsigned long)dst.ptr,
@@ -1044,7 +1045,7 @@ done_prefixes:
1044 if ((rc = ops->write_std( 1045 if ((rc = ops->write_std(
1045 register_address(ctxt->ss_base, 1046 register_address(ctxt->ss_base,
1046 _regs[VCPU_REGS_RSP]), 1047 _regs[VCPU_REGS_RSP]),
1047 dst.val, dst.bytes, ctxt)) != 0) 1048 &dst.val, dst.bytes, ctxt)) != 0)
1048 goto done; 1049 goto done;
1049 dst.val = dst.orig_val; /* skanky: disable writeback */ 1050 dst.val = dst.orig_val; /* skanky: disable writeback */
1050 break; 1051 break;
@@ -1077,12 +1078,12 @@ writeback:
1077 case OP_MEM: 1078 case OP_MEM:
1078 if (lock_prefix) 1079 if (lock_prefix)
1079 rc = ops->cmpxchg_emulated((unsigned long)dst. 1080 rc = ops->cmpxchg_emulated((unsigned long)dst.
1080 ptr, dst.orig_val, 1081 ptr, &dst.orig_val,
1081 dst.val, dst.bytes, 1082 &dst.val, dst.bytes,
1082 ctxt); 1083 ctxt);
1083 else 1084 else
1084 rc = ops->write_emulated((unsigned long)dst.ptr, 1085 rc = ops->write_emulated((unsigned long)dst.ptr,
1085 dst.val, dst.bytes, 1086 &dst.val, dst.bytes,
1086 ctxt); 1087 ctxt);
1087 if (rc != 0) 1088 if (rc != 0)
1088 goto done; 1089 goto done;
@@ -1320,36 +1321,8 @@ twobyte_special_insn:
1320 realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags); 1321 realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags);
1321 break; 1322 break;
1322 case 0xc7: /* Grp9 (cmpxchg8b) */ 1323 case 0xc7: /* Grp9 (cmpxchg8b) */
1323#if defined(__i386__)
1324 {
1325 unsigned long old_lo, old_hi;
1326 if (((rc = ops->read_emulated(cr2 + 0, &old_lo, 4,
1327 ctxt)) != 0)
1328 || ((rc = ops->read_emulated(cr2 + 4, &old_hi, 4,
1329 ctxt)) != 0))
1330 goto done;
1331 if ((old_lo != _regs[VCPU_REGS_RAX])
1332 || (old_hi != _regs[VCPU_REGS_RDX])) {
1333 _regs[VCPU_REGS_RAX] = old_lo;
1334 _regs[VCPU_REGS_RDX] = old_hi;
1335 _eflags &= ~EFLG_ZF;
1336 } else if (ops->cmpxchg8b_emulated == NULL) {
1337 rc = X86EMUL_UNHANDLEABLE;
1338 goto done;
1339 } else {
1340 if ((rc = ops->cmpxchg8b_emulated(cr2, old_lo,
1341 old_hi,
1342 _regs[VCPU_REGS_RBX],
1343 _regs[VCPU_REGS_RCX],
1344 ctxt)) != 0)
1345 goto done;
1346 _eflags |= EFLG_ZF;
1347 }
1348 break;
1349 }
1350#elif defined(CONFIG_X86_64)
1351 { 1324 {
1352 unsigned long old, new; 1325 u64 old, new;
1353 if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0) 1326 if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0)
1354 goto done; 1327 goto done;
1355 if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) || 1328 if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) ||
@@ -1358,15 +1331,15 @@ twobyte_special_insn:
1358 _regs[VCPU_REGS_RDX] = (u32) (old >> 32); 1331 _regs[VCPU_REGS_RDX] = (u32) (old >> 32);
1359 _eflags &= ~EFLG_ZF; 1332 _eflags &= ~EFLG_ZF;
1360 } else { 1333 } else {
1361 new = (_regs[VCPU_REGS_RCX] << 32) | (u32) _regs[VCPU_REGS_RBX]; 1334 new = ((u64)_regs[VCPU_REGS_RCX] << 32)
1362 if ((rc = ops->cmpxchg_emulated(cr2, old, 1335 | (u32) _regs[VCPU_REGS_RBX];
1363 new, 8, ctxt)) != 0) 1336 if ((rc = ops->cmpxchg_emulated(cr2, &old,
1337 &new, 8, ctxt)) != 0)
1364 goto done; 1338 goto done;
1365 _eflags |= EFLG_ZF; 1339 _eflags |= EFLG_ZF;
1366 } 1340 }
1367 break; 1341 break;
1368 } 1342 }
1369#endif
1370 } 1343 }
1371 goto writeback; 1344 goto writeback;
1372 1345