From: Mihai Donțu <mdo...@bitdefender.com>

There are cases where we need to emulate a CMPXCHG that touches two
pages (4 in one and another 4 in the next, for example). Because it
is not easy to map two pages in the kernel so that we can directly
execute the exchange instruction, we fallback to single-stepping.
Luckly, this is an uncommon occurrence making the overhead of the
single-step mechanism acceptable.

Signed-off-by: Mihai Donțu <mdo...@bitdefender.com>
Signed-off-by: Adalbert Lazăr <ala...@bitdefender.com>
---
 arch/x86/kvm/x86.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0e904782d303..e283b074db26 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5671,6 +5671,12 @@ static int emulator_cmpxchg_emulated(struct 
x86_emulate_ctxt *ctxt,
 #define CMPXCHG_MAX_BYTES 8
 #endif
 
+       gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, NULL);
+
+       if (gpa == UNMAPPED_GVA ||
+           (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
+               goto emul_write;
+
        /* guests cmpxchg{8,16}b have to be emulated atomically */
        if (bytes > CMPXCHG_MAX_BYTES || (bytes & (bytes - 1)))
                goto emul_write;
@@ -5678,12 +5684,6 @@ static int emulator_cmpxchg_emulated(struct 
x86_emulate_ctxt *ctxt,
        if (bytes == 16 && !system_has_cmpxchg_double())
                goto emul_write;
 
-       gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, NULL);
-
-       if (gpa == UNMAPPED_GVA ||
-           (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
-               goto emul_write;
-
        if (((gpa + bytes - 1) & PAGE_MASK) != (gpa & PAGE_MASK))
                goto emul_write;
 
@@ -5772,6 +5772,9 @@ static int emulator_cmpxchg_emulated(struct 
x86_emulate_ctxt *ctxt,
        return X86EMUL_CONTINUE;
 
 emul_write:
+       if (kvmi_tracked_gfn(vcpu, gpa >> PAGE_SHIFT))
+               return X86EMUL_UNHANDLEABLE;
+
        printk_once(KERN_WARNING "kvm: emulating exchange as write\n");
 
        return emulator_write_emulated(ctxt, addr, new, bytes, exception);
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to