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>
This commit is contained in:
parent
7dec5603b6
commit
ee212297cd
1 changed files with 5 additions and 5 deletions
|
@ -4736,17 +4736,17 @@ special_insn:
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
writeback:
|
writeback:
|
||||||
if (!(ctxt->d & NoWrite)) {
|
|
||||||
rc = writeback(ctxt, &ctxt->dst);
|
|
||||||
if (rc != X86EMUL_CONTINUE)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (ctxt->d & SrcWrite) {
|
if (ctxt->d & SrcWrite) {
|
||||||
BUG_ON(ctxt->src.type == OP_MEM || ctxt->src.type == OP_MEM_STR);
|
BUG_ON(ctxt->src.type == OP_MEM || ctxt->src.type == OP_MEM_STR);
|
||||||
rc = writeback(ctxt, &ctxt->src);
|
rc = writeback(ctxt, &ctxt->src);
|
||||||
if (rc != X86EMUL_CONTINUE)
|
if (rc != X86EMUL_CONTINUE)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (!(ctxt->d & NoWrite)) {
|
||||||
|
rc = writeback(ctxt, &ctxt->dst);
|
||||||
|
if (rc != X86EMUL_CONTINUE)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* restore dst type in case the decoding will be reused
|
* restore dst type in case the decoding will be reused
|
||||||
|
|
Loading…
Add table
Reference in a new issue