When a vCPU running in nested guest mode attempts to block (e.g., due to HLT), kvm_check_nested_events() may return -EBUSY to indicate that a nested event is pending but cannot be injected immediately, such as when event delivery is temporarily blocked in the guest. Currently, vcpu_block() logs a WARN_ON_ONCE() and then treats -EBUSY like any other error, returning 0 to exit to userspace. This can cause the vCPU to repeatedly block without making forward progress, delaying event injection and potentially leading to guest hangs under rare timing conditions. Remove the WARN_ON_ONCE() and handle -EBUSY explicitly by returning 1 to retry guest entry instead of exiting to userspace. This allows the nested event to be injected once the temporary blocking condition clears, ensuring forward progress. This issue was triggered by syzkaller while exercising nested virtualization. Fixes: 45405155d876 ("KVM: x86: WARN if a vCPU gets a valid wakeup that KVM can't yet inject") Reported-by: syzbot+1522459a74d26b0ac33a@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=1522459a74d26b0ac33a Tested-by: syzbot+1522459a74d26b0ac33a@syzkaller.appspotmail.com Signed-off-by: Alessandro Ratti --- arch/x86/kvm/x86.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ff8812f3a129..d5cf9a7ff8c5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11596,7 +11596,15 @@ static inline int vcpu_block(struct kvm_vcpu *vcpu) if (is_guest_mode(vcpu)) { int r = kvm_check_nested_events(vcpu); - WARN_ON_ONCE(r == -EBUSY); + /* + * -EBUSY indicates a nested event is pending but cannot be + * injected immediately (e.g., event delivery is temporarily + * blocked). Return to the vCPU run loop to retry guest entry + * instead of blocking, which would lose the pending event. + */ + if (r == -EBUSY) + return 1; + if (r < 0) return 0; } -- 2.52.0