aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorNadav Amit <namit@cs.technion.ac.il>2014-06-15 09:12:58 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-06-19 06:52:09 -0400
commitee212297cd425620867d4398d55d068c4203768c (patch)
tree693f75789abbef0339db3cf7a114b963cadae5a0 /arch
parent7dec5603b6b8dc4c3e1c65d318bd2a5a8c62a424 (diff)
KVM: x86: Wrong emulation on 'xadd X, X'
The emulator does not emulate the xadd instruction correctly if the two operands are the same. In this (unlikely) situation the result should be the sum of X and X (2X) when it is currently X. The solution is to first perform writeback to the source, before writing to the destination. The only instruction which should be affected is xadd, as the other instructions that perform writeback to the source use the extended accumlator (e.g., RAX:RDX). Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 439a3286406a..0d5ecbd45882 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -4736,17 +4736,17 @@ special_insn:
4736 goto done; 4736 goto done;
4737 4737
4738writeback: 4738writeback:
4739 if (!(ctxt->d & NoWrite)) {
4740 rc = writeback(ctxt, &ctxt->dst);
4741 if (rc != X86EMUL_CONTINUE)
4742 goto done;
4743 }
4744 if (ctxt->d & SrcWrite) { 4739 if (ctxt->d & SrcWrite) {
4745 BUG_ON(ctxt->src.type == OP_MEM || ctxt->src.type == OP_MEM_STR); 4740 BUG_ON(ctxt->src.type == OP_MEM || ctxt->src.type == OP_MEM_STR);
4746 rc = writeback(ctxt, &ctxt->src); 4741 rc = writeback(ctxt, &ctxt->src);
4747 if (rc != X86EMUL_CONTINUE) 4742 if (rc != X86EMUL_CONTINUE)
4748 goto done; 4743 goto done;
4749 } 4744 }
4745 if (!(ctxt->d & NoWrite)) {
4746 rc = writeback(ctxt, &ctxt->dst);
4747 if (rc != X86EMUL_CONTINUE)
4748 goto done;
4749 }
4750 4750
4751 /* 4751 /*
4752 * restore dst type in case the decoding will be reused 4752 * restore dst type in case the decoding will be reused