aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiran Alon <liran.alon@oracle.com>2017-11-05 09:07:43 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2017-11-17 07:20:21 -0500
commit917dc6068bc12a2dafffcf0e9d405ddb1b8780cb (patch)
tree972686a72e84b17b4cb6f46b238e8466756a2765
parentb200dded0a6974a3b69599832b2203483920ab25 (diff)
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 (commit acc9ab601327 ("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: acc9ab601327 ("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>
-rw-r--r--arch/x86/kvm/vmx.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 10474d26a000..be4724b5d434 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -11105,13 +11105,12 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
11105{ 11105{
11106 struct vcpu_vmx *vmx = to_vmx(vcpu); 11106 struct vcpu_vmx *vmx = to_vmx(vcpu);
11107 unsigned long exit_qual; 11107 unsigned long exit_qual;
11108 11108 bool block_nested_events =
11109 if (kvm_event_needs_reinjection(vcpu)) 11109 vmx->nested.nested_run_pending || kvm_event_needs_reinjection(vcpu);
11110 return -EBUSY;
11111 11110
11112 if (vcpu->arch.exception.pending && 11111 if (vcpu->arch.exception.pending &&
11113 nested_vmx_check_exception(vcpu, &exit_qual)) { 11112 nested_vmx_check_exception(vcpu, &exit_qual)) {
11114 if (vmx->nested.nested_run_pending) 11113 if (block_nested_events)
11115 return -EBUSY; 11114 return -EBUSY;
11116 nested_vmx_inject_exception_vmexit(vcpu, exit_qual); 11115 nested_vmx_inject_exception_vmexit(vcpu, exit_qual);
11117 vcpu->arch.exception.pending = false; 11116 vcpu->arch.exception.pending = false;
@@ -11120,14 +11119,14 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
11120 11119
11121 if (nested_cpu_has_preemption_timer(get_vmcs12(vcpu)) && 11120 if (nested_cpu_has_preemption_timer(get_vmcs12(vcpu)) &&
11122 vmx->nested.preemption_timer_expired) { 11121 vmx->nested.preemption_timer_expired) {
11123 if (vmx->nested.nested_run_pending) 11122 if (block_nested_events)
11124 return -EBUSY; 11123 return -EBUSY;
11125 nested_vmx_vmexit(vcpu, EXIT_REASON_PREEMPTION_TIMER, 0, 0); 11124 nested_vmx_vmexit(vcpu, EXIT_REASON_PREEMPTION_TIMER, 0, 0);
11126 return 0; 11125 return 0;
11127 } 11126 }
11128 11127
11129 if (vcpu->arch.nmi_pending && nested_exit_on_nmi(vcpu)) { 11128 if (vcpu->arch.nmi_pending && nested_exit_on_nmi(vcpu)) {
11130 if (vmx->nested.nested_run_pending) 11129 if (block_nested_events)
11131 return -EBUSY; 11130 return -EBUSY;
11132 nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI, 11131 nested_vmx_vmexit(vcpu, EXIT_REASON_EXCEPTION_NMI,
11133 NMI_VECTOR | INTR_TYPE_NMI_INTR | 11132 NMI_VECTOR | INTR_TYPE_NMI_INTR |
@@ -11143,7 +11142,7 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr)
11143 11142
11144 if ((kvm_cpu_has_interrupt(vcpu) || external_intr) && 11143 if ((kvm_cpu_has_interrupt(vcpu) || external_intr) &&
11145 nested_exit_on_intr(vcpu)) { 11144 nested_exit_on_intr(vcpu)) {
11146 if (vmx->nested.nested_run_pending) 11145 if (block_nested_events)
11147 return -EBUSY; 11146 return -EBUSY;
11148 nested_vmx_vmexit(vcpu, EXIT_REASON_EXTERNAL_INTERRUPT, 0, 0); 11147 nested_vmx_vmexit(vcpu, EXIT_REASON_EXTERNAL_INTERRUPT, 0, 0);
11149 return 0; 11148 return 0;