forked from Minki/linux
KVM: nVMX: Fix vmx_check_nested_events() return value in case an event was reinjected to L2
vmx_check_nested_events() should return -EBUSY only in case there is a pending L1 event which requires a VMExit from L2 to L1 but such a VMExit is currently blocked. Such VMExits are blocked either because nested_run_pending=1 or an event was reinjected to L2. vmx_check_nested_events() should return 0 in case there are no pending L1 events which requires a VMExit from L2 to L1 or if a VMExit from L2 to L1 was done internally. However, upstream commit which introduced blocking in case an event was reinjected to L2 (commitacc9ab6013
("KVM: nVMX: Fix pending events injection")) contains a bug: It returns -EBUSY even if there are no pending L1 events which requires VMExit from L2 to L1. This commit fix this issue. Fixes:acc9ab6013
("KVM: nVMX: Fix pending events injection") Signed-off-by: Liran Alon <liran.alon@oracle.com> Reviewed-by: Nikita Leshenko <nikita.leshchenko@oracle.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
This commit is contained in:
parent
b200dded0a
commit
917dc6068b
@ -11105,13 +11105,12 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
unsigned long exit_qual;
|
||||
|
||||
if (kvm_event_needs_reinjection(vcpu))
|
||||
return -EBUSY;
|
||||
bool block_nested_events =
|
||||
vmx->nested.nested_run_pending || kvm_event_needs_reinjection(vcpu);
|
||||
|
||||
if (vcpu->arch.exception.pending &&
|
||||
nested_vmx_check_exception(vcpu, &exit_qual)) {
|
||||
if (vmx->nested.nested_run_pending)
|
||||
if (block_nested_events)
|
||||
return -EBUSY;
|
||||
nested_vmx_inject_exception_vmexit(vcpu, exit_qual);
|
||||
vcpu->arch.exception.pending = false;
|
||||
@ -11120,14 +11119,14 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
|
||||
|
||||
if (nested_cpu_has_preemption_timer(get_vmcs12(vcpu)) &&
|
||||
vmx->nested.preemption_timer_expired) {
|
||||
if (vmx->nested.nested_run_pending)
|
||||
if (block_nested_events)
|
||||
return -EBUSY;
|
||||
nested_vmx_vmexit(vcpu, EXIT_REASON_PREEMPTION_TIMER, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vcpu->arch.nmi_pending && nested_exit_on_nmi(vcpu)) {
|
||||
if (vmx->nested.nested_run_pending)
|
||||
if (block_nested_events)
|
||||
return -EBUSY;
|
||||
nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
|
||||
NMI_VECTOR | INTR_TYPE_NMI_INTR |
|
||||
@ -11143,7 +11142,7 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
|
||||
|
||||
if ((kvm_cpu_has_interrupt(vcpu) || external_intr) &&
|
||||
nested_exit_on_intr(vcpu)) {
|
||||
if (vmx->nested.nested_run_pending)
|
||||
if (block_nested_events)
|
||||
return -EBUSY;
|
||||
nested_vmx_vmexit(vcpu, EXIT_REASON_EXTERNAL_INTERRUPT, 0, 0);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user