KVM: nVMX: Handle split-lock #AC exceptions that happen in L2
authorSean Christopherson <seanjc@google.com>
Tue, 22 Jun 2021 17:22:44 +0000 (10:22 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 Jul 2021 14:55:42 +0000 (16:55 +0200)
commit b33bb78a1fada6445c265c585ee0dd0fc6279102 upstream.

Mark #ACs that won't be reinjected to the guest as wanted by L0 so that
KVM handles split-lock #AC from L2 instead of forwarding the exception to
L1.  Split-lock #AC isn't yet virtualized, i.e. L1 will treat it like a
regular #AC and do the wrong thing, e.g. reinject it into L2.

Fixes: e6f8b6c12f03 ("KVM: VMX: Extend VMXs #AC interceptor to handle split lock #AC in guest")
Cc: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20210622172244.3561540-1-seanjc@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/vmcs.h
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/vmx/vmx.h

index 32e6f33c2c45b94a51c2b8a97274701f7f031b27..ec8803bdc575bf2059b82d4c84671b29959f60f2 100644 (file)
@@ -5787,6 +5787,9 @@ static bool nested_vmx_l0_wants_exit(struct kvm_vcpu *vcpu,
                else if (is_breakpoint(intr_info) &&
                         vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
                        return true;
+               else if (is_alignment_check(intr_info) &&
+                        !vmx_guest_inject_ac(vcpu))
+                       return true;
                return false;
        case EXIT_REASON_EXTERNAL_INTERRUPT:
                return true;
index 1472c6c376f74a661d053c616f648556019da64a..571d9ad80a59ebac719f3937c07d3c7b8f5a90bc 100644 (file)
@@ -117,6 +117,11 @@ static inline bool is_gp_fault(u32 intr_info)
        return is_exception_n(intr_info, GP_VECTOR);
 }
 
+static inline bool is_alignment_check(u32 intr_info)
+{
+       return is_exception_n(intr_info, AC_VECTOR);
+}
+
 static inline bool is_machine_check(u32 intr_info)
 {
        return is_exception_n(intr_info, MC_VECTOR);
index 45877364e6829168af0b94910d7319c80393f0c6..de24d3826788af8aec7a56e51e45b6112c354635 100644 (file)
@@ -4755,7 +4755,7 @@ static int handle_machine_check(struct kvm_vcpu *vcpu)
  *  - Guest has #AC detection enabled in CR0
  *  - Guest EFLAGS has AC bit set
  */
-static inline bool guest_inject_ac(struct kvm_vcpu *vcpu)
+bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu)
 {
        if (!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT))
                return true;
@@ -4864,7 +4864,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
                kvm_run->debug.arch.exception = ex_no;
                break;
        case AC_VECTOR:
-               if (guest_inject_ac(vcpu)) {
+               if (vmx_guest_inject_ac(vcpu)) {
                        kvm_queue_exception_e(vcpu, AC_VECTOR, error_code);
                        return 1;
                }
index ae3a89ac0600d4f420a192bb74abf2806232b765..73d87d44b65782a772b10ef29ee07058ba957215 100644 (file)
@@ -352,6 +352,7 @@ void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
 u64 construct_eptp(struct kvm_vcpu *vcpu, unsigned long root_hpa,
                   int root_level);
 
+bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu);
 void update_exception_bitmap(struct kvm_vcpu *vcpu);
 void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu);
 bool vmx_nmi_blocked(struct kvm_vcpu *vcpu);