Merge tag 'kvm-s390-master-5.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / arch / x86 / kvm / x86.c
index 919d3c8f9b6561d7b927a2dd9a6fdc9a38468f6f..c5835f9cb9ad327aba58c1cab2a47934f5807d53 100644 (file)
@@ -5856,6 +5856,7 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
 {
        struct kvm_host_map map;
        struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
+       u64 page_line_mask;
        gpa_t gpa;
        char *kaddr;
        bool exchanged;
@@ -5870,7 +5871,16 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
            (gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
                goto emul_write;
 
-       if (((gpa + bytes - 1) & PAGE_MASK) != (gpa & PAGE_MASK))
+       /*
+        * Emulate the atomic as a straight write to avoid #AC if SLD is
+        * enabled in the host and the access splits a cache line.
+        */
+       if (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT))
+               page_line_mask = ~(cache_line_size() - 1);
+       else
+               page_line_mask = PAGE_MASK;
+
+       if (((gpa + bytes - 1) & page_line_mask) != (gpa & page_line_mask))
                goto emul_write;
 
        if (kvm_vcpu_map(vcpu, gpa_to_gfn(gpa), &map))