From: Jim Mattson <jmattson@xxxxxxxxxx> If kvm_check_nested_events fails due to raising an EXIT_REASON_INTERNAL_ERROR, propagate it to userspace immediately, even if the vCPU would otherwise be sleeping. This happens for example when the posted interrupt descriptor points outside guest memory. Reported-by: Jim Mattson <jmattson@xxxxxxxxxx> Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- arch/x86/kvm/x86.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 348452bb16bc..916c976e99ab 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9752,10 +9752,14 @@ static inline int vcpu_block(struct kvm *kvm, struct kvm_vcpu *vcpu) return 1; } -static inline bool kvm_vcpu_running(struct kvm_vcpu *vcpu) +static inline int kvm_vcpu_running(struct kvm_vcpu *vcpu) { - if (is_guest_mode(vcpu)) - kvm_check_nested_events(vcpu); + int r; + if (is_guest_mode(vcpu)) { + r = kvm_check_nested_events(vcpu); + if (r < 0 && r != -EBUSY) + return r; + } return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE && !vcpu->arch.apf.halted); @@ -9770,12 +9774,16 @@ static int vcpu_run(struct kvm_vcpu *vcpu) vcpu->arch.l1tf_flush_l1d = true; for (;;) { - if (kvm_vcpu_running(vcpu)) { - r = vcpu_enter_guest(vcpu); - } else { - r = vcpu_block(kvm, vcpu); + r = kvm_vcpu_running(vcpu); + if (r < 0) { + r = 0; + break; } + if (r) + r = vcpu_enter_guest(vcpu); + else + r = vcpu_block(kvm, vcpu); if (r <= 0) break; -- 2.27.0