Commit b33bb78a authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini

KVM: nVMX: Handle split-lock #AC exceptions that happen in L2

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: e6f8b6c1 ("KVM: VMX: Extend VMXs #AC interceptor to handle split lock #AC in guest")
Cc: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
Message-Id: <20210622172244.3561540-1-seanjc@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 31c65657
...@@ -5833,6 +5833,9 @@ static bool nested_vmx_l0_wants_exit(struct kvm_vcpu *vcpu, ...@@ -5833,6 +5833,9 @@ static bool nested_vmx_l0_wants_exit(struct kvm_vcpu *vcpu,
else if (is_breakpoint(intr_info) && else if (is_breakpoint(intr_info) &&
vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
return true; return true;
else if (is_alignment_check(intr_info) &&
!vmx_guest_inject_ac(vcpu))
return true;
return false; return false;
case EXIT_REASON_EXTERNAL_INTERRUPT: case EXIT_REASON_EXTERNAL_INTERRUPT:
return true; return true;
......
...@@ -117,6 +117,11 @@ static inline bool is_gp_fault(u32 intr_info) ...@@ -117,6 +117,11 @@ static inline bool is_gp_fault(u32 intr_info)
return is_exception_n(intr_info, GP_VECTOR); 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) static inline bool is_machine_check(u32 intr_info)
{ {
return is_exception_n(intr_info, MC_VECTOR); return is_exception_n(intr_info, MC_VECTOR);
......
...@@ -4743,7 +4743,7 @@ static int handle_machine_check(struct kvm_vcpu *vcpu) ...@@ -4743,7 +4743,7 @@ static int handle_machine_check(struct kvm_vcpu *vcpu)
* - Guest has #AC detection enabled in CR0 * - Guest has #AC detection enabled in CR0
* - Guest EFLAGS has AC bit set * - 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)) if (!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT))
return true; return true;
...@@ -4851,7 +4851,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) ...@@ -4851,7 +4851,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
kvm_run->debug.arch.exception = ex_no; kvm_run->debug.arch.exception = ex_no;
break; break;
case AC_VECTOR: case AC_VECTOR:
if (guest_inject_ac(vcpu)) { if (vmx_guest_inject_ac(vcpu)) {
kvm_queue_exception_e(vcpu, AC_VECTOR, error_code); kvm_queue_exception_e(vcpu, AC_VECTOR, error_code);
return 1; return 1;
} }
......
...@@ -376,6 +376,7 @@ void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); ...@@ -376,6 +376,7 @@ void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level); u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level);
bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu);
void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu); void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu);
void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu); void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu);
bool vmx_nmi_blocked(struct kvm_vcpu *vcpu); bool vmx_nmi_blocked(struct kvm_vcpu *vcpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment