summaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2010-07-15 02:51:58 +0200
committerAvi Kivity <avi@redhat.com>2010-08-02 05:40:53 +0200
commitc19b8bd60e19308d5583ef200ddcc782d85d9543 (patch)
treeac58a35ca5f79a4bf5f36445ecc8e7d2c10178b4 /arch/x86
parentKVM: x86: Call mask notifiers from pic (diff)
downloadlinux-c19b8bd60e19308d5583ef200ddcc782d85d9543.tar.xz
linux-c19b8bd60e19308d5583ef200ddcc782d85d9543.zip
KVM: x86 emulator: fix xchg instruction emulation
If the destination is a memory operand and the memory cannot map to a valid page, the xchg instruction emulation and locked instruction will not work on io regions and stuck in endless loop. We should emulate exchange as write to fix it. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Acked-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/x86.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 689c2c3182ab..97aab036dabf 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3562,6 +3562,10 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
goto emul_write;
page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+ if (is_error_page(page)) {
+ kvm_release_page_clean(page);
+ goto emul_write;
+ }
kaddr = kmap_atomic(page, KM_USER0);
kaddr += offset_in_page(gpa);