All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "David Woodhouse" <dwmw2@infradead.org>, kvm@vger.kernel.org
Subject: Re: [PATCH 05/10] KVM: x86/xen: Retry event channel delivery which races a memslot update
Date: Tue, 13 Oct 2026 21:17:18 +0000	[thread overview]
Message-ID: <sashiko-outbox-170525@kernel.org> (raw)
In-Reply-To: <20261013204824.454208-6-dwmw2@infradead.org>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] kvm: infinite loop in vcpu_run due to Xen timer delivery failure
- [High] kvm: ABBA deadlock between xen_lock and kvm->srcu in KVM_XEN_HVM_SET_ATTR
--

commit b27b9db29f6c5d0bc3a62af7e5baefbb8e0f7c51
Author: David Woodhouse <dwmw@amazon.co.uk>

KVM: x86/xen: Retry event channel delivery which races a memslot update

Event channel delivery now returns -EAGAIN when it races a memslot
update. It always failed; now the failure is distinguishable, and
instead of dropping the event each caller reacts according to its
context.

Closes: https://lore.kernel.org/all/20260920215341.5ECE91F000FF@smtp.kernel.org

> diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
> index aea6572163d0c..ad7708be6c049 100644
> --- a/arch/x86/kvm/xen.c
> +++ b/arch/x86/kvm/xen.c
> @@ -113,7 +114,7 @@ void kvm_xen_inject_timer_irqs(struct kvm_vcpu *vcpu)
>  		e.port = vcpu->arch.xen.timer_virq;
>  		e.priority = KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL;
>  
> -		rc = kvm_xen_set_evtchn(&e, vcpu->kvm);
> +		rc = kvm_xen_set_evtchn(&e, vcpu->kvm, wait);
>  
>  		/*
>  		 * Deliberately leave timer_pending set if the memslot is

[Severity: High]
Does this code cause an infinite loop in vcpu_run() due to the Xen timer
delivery failure?

If rc is -EAGAIN or -EINVAL, timer_pending remains set. A set
timer_pending causes block attempts to instantly abort:

virt/kvm/kvm_main.c:kvm_vcpu_check_block() {
    ...
	if (kvm_cpu_has_pending_timer(vcpu))
		goto out;
	if (signal_pending(current))
		goto out;
    ...
}

Because the block is aborted and kvm_vcpu_has_events() evaluates to false
(as it does not check timer_pending), the vCPU's mp_state remains halted.

This forces vcpu_run() into an infinite retry loop on the host core
without entering the guest:

arch/x86/kvm/x86.c:vcpu_run() {
    ...
		if (kvm_vcpu_running(vcpu)) {
			r = vcpu_enter_guest(vcpu);
		} else {
			r = vcpu_block(vcpu);
		}

		if (r <= 0)
			break;

		kvm_clear_request(KVM_REQ_UNBLOCK, vcpu);
		...
		if (kvm_cpu_has_pending_timer(vcpu))
			kvm_inject_pending_timer_irqs(vcpu);
    ...
}

[ ... ]

> @@ -2020,16 +2036,13 @@ static int kvm_xen_set_evtchn(struct kvm_xen_evtchn *xe, struct kvm *kvm)
>  	 */
>  	do {
>  		struct gfn_to_pfn_cache *gpc = &kvm->arch.xen.shinfo_cache;
> -		int idx;
>  
>  		rc = kvm_xen_set_evtchn_fast(xe, kvm);
>  		if (rc != -EWOULDBLOCK)
>  			break;
>  
> -		idx = srcu_read_lock(&kvm->srcu);
> -		rc = kvm_gpc_refresh(gpc, PAGE_SIZE, false);
> -		srcu_read_unlock(&kvm->srcu, idx);
> -	} while(!rc);
> +		rc = kvm_gpc_refresh(gpc, PAGE_SIZE, wait);
> +	} while (!rc);
>  
>  	if (mm_borrowed)
>  		kthread_unuse_mm(kvm->mm);

[Severity: High]
Can this cause a deadlock between xen_lock and kvm->srcu?

The SET_ATTR ioctl for LONG_MODE acquires xen_lock and calls
kvm_xen_shared_info_init() with wait=true:

arch/x86/kvm/xen.c:kvm_xen_hvm_set_attr() {
    mutex_lock(&kvm->arch.xen.xen_lock);
    ...
    r = kvm->arch.xen.shinfo_cache.active ?
        kvm_xen_shared_info_init(kvm, true) : 0;
    mutex_unlock(&kvm->arch.xen.xen_lock);
}

This causes it to sleep waiting for memslot updates while holding
xen_lock.

Meanwhile, a vCPU running in guest mode (holding kvm->srcu read lock)
can block trying to acquire xen_lock in kvm_xen_write_hypercall_page():

arch/x86/kvm/xen.c:kvm_xen_write_hypercall_page() {
    mutex_lock(&kvm->arch.xen.xen_lock);
}

This prevents synchronize_srcu() in the memslot update from completing,
resulting in an ABBA deadlock.

The SHARED_INFO case similarly acquires xen_lock and explicitly loops in
kvm_gpc_activate() and kvm_gpc_refresh() with wait=true while holding
the lock.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261013204824.454208-1-dwmw2@infradead.org?part=5

  reply	other threads:[~2026-10-13 21:17 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13 20:48 [PATCH 00/10] KVM: x86/xen: Don't drop event deliveries which race memslot updates David Woodhouse
2026-10-13 20:48 ` [PATCH 01/10] KVM: pfncache: Return -EAGAIN for a lookup which hits an invalid memslot David Woodhouse
2026-10-13 20:48 ` [PATCH 02/10] KVM: pfncache: Add a 'wait' argument to the refresh and activate functions David Woodhouse
2026-10-13 20:48 ` [PATCH 03/10] KVM: x86/xen: Wait out memslot updates in the Xen attribute ioctls David Woodhouse
2026-10-13 21:04   ` sashiko-bot
2026-10-13 21:33     ` David Woodhouse
2026-10-13 20:48 ` [PATCH 04/10] KVM: x86/xen: Don't lose the timer event when delivery fails transiently David Woodhouse
2026-10-13 21:06   ` sashiko-bot
2026-10-13 20:48 ` [PATCH 05/10] KVM: x86/xen: Retry event channel delivery which races a memslot update David Woodhouse
2026-10-13 21:17   ` sashiko-bot [this message]
2026-10-13 20:48 ` [PATCH 06/10] KVM: x86/xen: Extract delivery of event to vCPU into a separate helper David Woodhouse
2026-10-13 20:48 ` [PATCH 07/10] KVM: x86/xen: Explicitly tag "shared info" page as never being dirty tracked David Woodhouse
2026-10-13 20:48 ` [PATCH 08/10] KVM: x86/xen: Don't dirty track "vCPU info" page David Woodhouse
2026-10-13 20:48 ` [PATCH 09/10] KVM: x86: Request the guest TLB flush from record_steal_time() David Woodhouse
2026-10-13 20:48 ` [PATCH 10/10] KVM: selftests: Add Xen evtchn vs memslot-update race test David Woodhouse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-170525@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dwmw2@infradead.org \
    --cc=kvm@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.