Commit 4020da3b authored by Maxim Levitsky's avatar Maxim Levitsky Committed by Paolo Bonzini

KVM: x86: pending exceptions must not be blocked by an injected event

Injected interrupts/nmi should not block a pending exception,
but rather be either lost if nested hypervisor doesn't
intercept the pending exception (as in stock x86), or be delivered
in exitintinfo/IDT_VECTORING_INFO field, as a part of a VMexit
that corresponds to the pending exception.

The only reason for an exception to be blocked is when nested run
is pending (and that can't really happen currently
but still worth checking for).
Signed-off-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
Message-Id: <20210401143817.1030695-2-mlevitsk@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent b9c36fde
...@@ -1062,7 +1062,13 @@ static int svm_check_nested_events(struct kvm_vcpu *vcpu) ...@@ -1062,7 +1062,13 @@ static int svm_check_nested_events(struct kvm_vcpu *vcpu)
} }
if (vcpu->arch.exception.pending) { if (vcpu->arch.exception.pending) {
if (block_nested_events) /*
* Only a pending nested run can block a pending exception.
* Otherwise an injected NMI/interrupt should either be
* lost or delivered to the nested hypervisor in the EXITINTINFO
* vmcb field, while delivering the pending exception.
*/
if (svm->nested.nested_run_pending)
return -EBUSY; return -EBUSY;
if (!nested_exit_on_exception(svm)) if (!nested_exit_on_exception(svm))
return 0; return 0;
......
...@@ -3806,9 +3806,15 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu) ...@@ -3806,9 +3806,15 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu)
/* /*
* Process any exceptions that are not debug traps before MTF. * Process any exceptions that are not debug traps before MTF.
*
* Note that only a pending nested run can block a pending exception.
* Otherwise an injected NMI/interrupt should either be
* lost or delivered to the nested hypervisor in the IDT_VECTORING_INFO,
* while delivering the pending exception.
*/ */
if (vcpu->arch.exception.pending && !vmx_pending_dbg_trap(vcpu)) { if (vcpu->arch.exception.pending && !vmx_pending_dbg_trap(vcpu)) {
if (block_nested_events) if (vmx->nested.nested_run_pending)
return -EBUSY; return -EBUSY;
if (!nested_vmx_check_exception(vcpu, &exit_qual)) if (!nested_vmx_check_exception(vcpu, &exit_qual))
goto no_vmexit; goto no_vmexit;
...@@ -3825,7 +3831,7 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu) ...@@ -3825,7 +3831,7 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu)
} }
if (vcpu->arch.exception.pending) { if (vcpu->arch.exception.pending) {
if (block_nested_events) if (vmx->nested.nested_run_pending)
return -EBUSY; return -EBUSY;
if (!nested_vmx_check_exception(vcpu, &exit_qual)) if (!nested_vmx_check_exception(vcpu, &exit_qual))
goto no_vmexit; goto no_vmexit;
......
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