summaryrefslogtreecommitdiff
path: root/arch/x86
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2008-05-21 15:34:25 +0300
committerAvi Kivity <avi@qumranet.com>2008-06-06 21:08:25 +0300
commit33e3885de25148e00595c4dd808d6eb15db2edcf (patch)
treed7bc06e1ff57b59d70b23ee4b175e0ae2f45e708 /arch/x86
parentf20d2752980c144c82649eb18746ef0c29f508dd (diff)
downloadlinux-3.10-33e3885de25148e00595c4dd808d6eb15db2edcf.tar.gz
linux-3.10-33e3885de25148e00595c4dd808d6eb15db2edcf.tar.bz2
linux-3.10-33e3885de25148e00595c4dd808d6eb15db2edcf.zip
KVM: x86 emulator: fix hypercall return value on AMD
The hypercall instructions on Intel and AMD are different. KVM allows the guest to choose one or the other (the default is Intel), and if the guest chooses incorrectly, KVM will patch it at runtime to select the correct instruction. This allows live migration between Intel and AMD machines. This patching occurs in the x86 emulator. The current code also executes the hypercall. Unfortunately, the tail end of the x86 emulator code also executes, overwriting the return value of the hypercall with the original contents of rax (which happens to be the hypercall number). Fix not by executing the hypercall in the emulator context; instead let the guest reissue the patched instruction and execute the hypercall via the normal path. Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/x86_emulate.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index 8a96320ab07..932f216d890 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -1727,7 +1727,8 @@ twobyte_insn:
if (rc)
goto done;
- kvm_emulate_hypercall(ctxt->vcpu);
+ /* Let the processor re-execute the fixed hypercall */
+ c->eip = ctxt->vcpu->arch.rip;
/* Disable writeback. */
c->dst.type = OP_NONE;
break;