FAILED: patch "[PATCH] xen/events: Return -EEXIST for bound VIRQs" failed to apply to 6.1-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 07ce121d93a5e5fb2440a24da3dbf408fcee978e
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025101625-gully-disaster-8717@gregkh' --subject-prefix 'PATCH 6.1.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 07ce121d93a5e5fb2440a24da3dbf408fcee978e Mon Sep 17 00:00:00 2001
From: Jason Andryuk <[email protected]>
Date: Wed, 27 Aug 2025 20:36:02 -0400
Subject: [PATCH] xen/events: Return -EEXIST for bound VIRQs
Change find_virq() to return -EEXIST when a VIRQ is bound to a different CPU than the one passed in. With that, remove the BUG_ON() from bind_virq_to_irq() to propogate the error upwards.
Some VIRQs are per-cpu, but others are per-domain or global. Those must be bound to CPU0 and can then migrate elsewhere. The lookup for per-domain and global will probably fail when migrated off CPU 0, especially when the current CPU is tracked. This now returns -EEXIST instead of BUG_ON().
A second call to bind a per-domain or global VIRQ is not expected, but make it non-fatal to avoid trying to look up the irq, since we don't know which per_cpu(virq_to_irq) it will be in.
Message-ID: <[email protected]>
drivers/xen/events/events_base.c +14 -5
@@ -1314,10 +1314,12 @@ int bind_interdomain_evtchn_to_irq_lateeoi(struct xenbus_device *dev, }EXPORT_SYMBOL_GPL (bind_interdomain_evtchn_to_irq_lateeoi); -static int find_virq (unsigned int virq,unsigned int cpu,evtchn_port_t *evtchn) +static int find_virq (unsigned int virq,unsigned int cpu,evtchn_port_t *evtchn, +bool percpu) {struct evtchn_status status;evtchn_port_t port; +bool exists = false;memset (&status,0 ,sizeof (status));for (port =0 ; port <xen_evtchn_max_channels (); port++) {
@@ -1330,12 +1332,16 @@ static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn)continue ;if (status.status != EVTCHNSTAT_virq)continue ; -if (status.u.virq == virq && status.vcpu ==xen_vcpu_nr (cpu)) { +if (status.u.virq != virq) +continue ; +if (status.vcpu ==xen_vcpu_nr (cpu)) { *evtchn = port;return 0 ; + }else if (!percpu) { + exists = true; } } -return -ENOENT ; +return exists ? -EEXIST : -ENOENT ; }/**
@@ -1382,8 +1388,11 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu, bool percpu) evtchn = bind_virq.port; else {if (ret == -EEXIST ) - ret =find_virq (virq, cpu, &evtchn); -BUG_ON (ret <0 ); + ret =find_virq (virq, cpu, &evtchn, percpu); +if (ret) { +__unbind_from_irq (info, info->irq); + goto out; + } } ret =xen_irq_info_virq_setup (info, cpu, evtchn, virq);