* [PATCH v2 0/3] xen/events: Fix Global and Domain VIRQ tracking
@ 2025-08-26 0:55 Jason Andryuk
2025-08-26 0:55 ` [PATCH v2 1/3] xen/events: Cleanup find_virq() return codes Jason Andryuk
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Jason Andryuk @ 2025-08-26 0:55 UTC (permalink / raw)
To: Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko
Cc: Jason Andryuk, xen-devel, linux-kernel
v2 is now a series first changing find_virq() to return -EEXIST in some
cases, and then tracking cpu movement of VIRQs. This keeps ensures the
cpu is correct when calling unbind_from_irq().
Jason Andryuk (3):
xen/events: Cleanup find_virq() return codes
xen/events: Return -EEXIST for bound VIRQs
xen/events: Update virq_to_irq on migration
drivers/xen/events/events_base.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
--
2.50.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/3] xen/events: Cleanup find_virq() return codes
2025-08-26 0:55 [PATCH v2 0/3] xen/events: Fix Global and Domain VIRQ tracking Jason Andryuk
@ 2025-08-26 0:55 ` Jason Andryuk
2025-08-26 7:22 ` Jan Beulich
2025-08-26 0:55 ` [PATCH v2 2/3] xen/events: Return -EEXIST for bound VIRQs Jason Andryuk
2025-08-26 0:55 ` [PATCH v2 3/3] xen/events: Update virq_to_irq on migration Jason Andryuk
2 siblings, 1 reply; 10+ messages in thread
From: Jason Andryuk @ 2025-08-26 0:55 UTC (permalink / raw)
To: Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko
Cc: Jason Andryuk, xen-devel, linux-kernel
rc is overwritten by the evtchn_status hypercall in each iteration, so
the return value will be whatever the last iteration is. Change to an
explicit -ENOENT for an un-found virq and return 0 on a successful
match.
Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
---
v2:
New
---
drivers/xen/events/events_base.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 41309d38f78c..199afe59f357 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -1318,7 +1318,7 @@ static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn)
{
struct evtchn_status status;
evtchn_port_t port;
- int rc = -ENOENT;
+ int rc;
memset(&status, 0, sizeof(status));
for (port = 0; port < xen_evtchn_max_channels(); port++) {
@@ -1331,10 +1331,10 @@ static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn)
continue;
if (status.u.virq == virq && status.vcpu == xen_vcpu_nr(cpu)) {
*evtchn = port;
- break;
+ return 0;
}
}
- return rc;
+ return -ENOENT;
}
/**
--
2.50.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/3] xen/events: Return -EEXIST for bound VIRQs
2025-08-26 0:55 [PATCH v2 0/3] xen/events: Fix Global and Domain VIRQ tracking Jason Andryuk
2025-08-26 0:55 ` [PATCH v2 1/3] xen/events: Cleanup find_virq() return codes Jason Andryuk
@ 2025-08-26 0:55 ` Jason Andryuk
2025-08-27 15:21 ` Jürgen Groß
2025-08-26 0:55 ` [PATCH v2 3/3] xen/events: Update virq_to_irq on migration Jason Andryuk
2 siblings, 1 reply; 10+ messages in thread
From: Jason Andryuk @ 2025-08-26 0:55 UTC (permalink / raw)
To: Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko
Cc: Jason Andryuk, xen-devel, linux-kernel
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.
Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
---
V2:
New
---
drivers/xen/events/events_base.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 199afe59f357..a85bc43f4344 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -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;
int rc;
memset(&status, 0, sizeof(status));
@@ -1329,12 +1331,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;
}
/**
@@ -1381,8 +1387,9 @@ 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)
+ goto out;
}
ret = xen_irq_info_virq_setup(info, cpu, evtchn, virq);
--
2.50.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/3] xen/events: Update virq_to_irq on migration
2025-08-26 0:55 [PATCH v2 0/3] xen/events: Fix Global and Domain VIRQ tracking Jason Andryuk
2025-08-26 0:55 ` [PATCH v2 1/3] xen/events: Cleanup find_virq() return codes Jason Andryuk
2025-08-26 0:55 ` [PATCH v2 2/3] xen/events: Return -EEXIST for bound VIRQs Jason Andryuk
@ 2025-08-26 0:55 ` Jason Andryuk
2025-08-27 15:28 ` Jürgen Groß
2 siblings, 1 reply; 10+ messages in thread
From: Jason Andryuk @ 2025-08-26 0:55 UTC (permalink / raw)
To: Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
Chris Wright, Jeremy Fitzhardinge
Cc: Jason Andryuk, stable, xen-devel, linux-kernel
VIRQs come in 3 flavors, per-VPU, per-domain, and global, and the VIRQs
are tracked in per-cpu virq_to_irq arrays.
Per-domain and global VIRQs must be bound on CPU 0, and
bind_virq_to_irq() sets the per_cpu virq_to_irq at registration time
Later, the interrupt can migrate, and info->cpu is updated. When
calling __unbind_from_irq(), the per-cpu virq_to_irq is cleared for a
different cpu. If bind_virq_to_irq() is called again with CPU 0, the
stale irq is returned. There won't be any irq_info for the irq, so
things break.
Make xen_rebind_evtchn_to_cpu() update the per_cpu virq_to_irq mappings
to keep them update to date with the current cpu. This ensures the
correct virq_to_irq is cleared in __unbind_from_irq().
Fixes: e46cdb66c8fc ("xen: event channels")
Cc: stable@vger.kernel.org
Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
---
V2:
Different approach changing virq_to_irq
---
drivers/xen/events/events_base.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index a85bc43f4344..4e9db7b92dde 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -1772,6 +1772,7 @@ static int xen_rebind_evtchn_to_cpu(struct irq_info *info, unsigned int tcpu)
{
struct evtchn_bind_vcpu bind_vcpu;
evtchn_port_t evtchn = info ? info->evtchn : 0;
+ int old_cpu = info ? info->cpu : tcpu;
if (!VALID_EVTCHN(evtchn))
return -1;
@@ -1795,8 +1796,18 @@ static int xen_rebind_evtchn_to_cpu(struct irq_info *info, unsigned int tcpu)
* it, but don't do the xenlinux-level rebind in that case.
*/
if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
+ {
bind_evtchn_to_cpu(info, tcpu, false);
+ if (info->type == IRQT_VIRQ) {
+ int virq = info->u.virq;
+ int irq = per_cpu(virq_to_irq, old_cpu)[virq];
+
+ per_cpu(virq_to_irq, old_cpu)[virq] = -1;
+ per_cpu(virq_to_irq, tcpu)[virq] = irq;
+ }
+ }
+
do_unmask(info, EVT_MASK_REASON_TEMPORARY);
return 0;
--
2.50.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/3] xen/events: Cleanup find_virq() return codes
2025-08-26 0:55 ` [PATCH v2 1/3] xen/events: Cleanup find_virq() return codes Jason Andryuk
@ 2025-08-26 7:22 ` Jan Beulich
2025-08-26 15:03 ` Jason Andryuk
0 siblings, 1 reply; 10+ messages in thread
From: Jan Beulich @ 2025-08-26 7:22 UTC (permalink / raw)
To: Jason Andryuk
Cc: xen-devel, linux-kernel, Juergen Gross, Stefano Stabellini,
Oleksandr Tyshchenko
On 26.08.2025 02:55, Jason Andryuk wrote:
> rc is overwritten by the evtchn_status hypercall in each iteration, so
> the return value will be whatever the last iteration is.
Which may even be a false "success". Especially for that it feels like ...
> Change to an
> explicit -ENOENT for an un-found virq and return 0 on a successful
> match.
>
> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
... this also wants a Fixes: tag and perhaps a Cc: to stable@.
> --- a/drivers/xen/events/events_base.c
> +++ b/drivers/xen/events/events_base.c
> @@ -1318,7 +1318,7 @@ static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn)
> {
> struct evtchn_status status;
> evtchn_port_t port;
> - int rc = -ENOENT;
> + int rc;
Maybe best to also move this into the more narrow scope (loop body)?
Either way:
Reviewed-by: Jan Beulich <jbeulich@suse.com>
> memset(&status, 0, sizeof(status));
Having this outside of the loop is a little odd, too: It makes assumptions
on the behavior of the hypervisor (like not altering the structure upon
error). Yet likely not something to deal with right here.
Jan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/3] xen/events: Cleanup find_virq() return codes
2025-08-26 7:22 ` Jan Beulich
@ 2025-08-26 15:03 ` Jason Andryuk
2025-08-27 15:16 ` Jürgen Groß
0 siblings, 1 reply; 10+ messages in thread
From: Jason Andryuk @ 2025-08-26 15:03 UTC (permalink / raw)
To: Jan Beulich
Cc: xen-devel, linux-kernel, Juergen Gross, Stefano Stabellini,
Oleksandr Tyshchenko
On 2025-08-26 03:22, Jan Beulich wrote:
> On 26.08.2025 02:55, Jason Andryuk wrote:
>> rc is overwritten by the evtchn_status hypercall in each iteration, so
>> the return value will be whatever the last iteration is.
>
> Which may even be a false "success". Especially for that it feels like ...
I'll state that here...
>
>> Change to an
>> explicit -ENOENT for an un-found virq and return 0 on a successful
>> match.
>>
>> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
>
> ... this also wants a Fixes: tag and perhaps a Cc: to stable@.
and add these.
>
>> --- a/drivers/xen/events/events_base.c
>> +++ b/drivers/xen/events/events_base.c
>> @@ -1318,7 +1318,7 @@ static int find_virq(unsigned int virq, unsigned int cpu, evtchn_port_t *evtchn)
>> {
>> struct evtchn_status status;
>> evtchn_port_t port;
>> - int rc = -ENOENT;
>> + int rc;
>
> Maybe best to also move this into the more narrow scope (loop body)?
Sounds good.
> Either way:
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
Thanks.
>
>> memset(&status, 0, sizeof(status));
>
> Having this outside of the loop is a little odd, too: It makes assumptions
> on the behavior of the hypervisor (like not altering the structure upon
> error). Yet likely not something to deal with right here.
Agreed.
Thanks,
Jason
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/3] xen/events: Cleanup find_virq() return codes
2025-08-26 15:03 ` Jason Andryuk
@ 2025-08-27 15:16 ` Jürgen Groß
0 siblings, 0 replies; 10+ messages in thread
From: Jürgen Groß @ 2025-08-27 15:16 UTC (permalink / raw)
To: Jason Andryuk, Jan Beulich
Cc: xen-devel, linux-kernel, Stefano Stabellini, Oleksandr Tyshchenko
[-- Attachment #1.1.1: Type: text/plain, Size: 1271 bytes --]
On 26.08.25 17:03, Jason Andryuk wrote:
> On 2025-08-26 03:22, Jan Beulich wrote:
>> On 26.08.2025 02:55, Jason Andryuk wrote:
>>> rc is overwritten by the evtchn_status hypercall in each iteration, so
>>> the return value will be whatever the last iteration is.
>>
>> Which may even be a false "success". Especially for that it feels like ...
>
> I'll state that here...
>
>>
>>> Change to an
>>> explicit -ENOENT for an un-found virq and return 0 on a successful
>>> match.
>>>
>>> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
>>
>> ... this also wants a Fixes: tag and perhaps a Cc: to stable@.
>
> and add these.
>
>>
>>> --- a/drivers/xen/events/events_base.c
>>> +++ b/drivers/xen/events/events_base.c
>>> @@ -1318,7 +1318,7 @@ static int find_virq(unsigned int virq, unsigned int
>>> cpu, evtchn_port_t *evtchn)
>>> {
>>> struct evtchn_status status;
>>> evtchn_port_t port;
>>> - int rc = -ENOENT;
>>> + int rc;
>>
>> Maybe best to also move this into the more narrow scope (loop body)?
>
> Sounds good.
>
>> Either way:
>> Reviewed-by: Jan Beulich <jbeulich@suse.com>
With the changes you promised to do:
Reviewed-by: Juergen Gross <jgross@suse.com>
Juergen
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/3] xen/events: Return -EEXIST for bound VIRQs
2025-08-26 0:55 ` [PATCH v2 2/3] xen/events: Return -EEXIST for bound VIRQs Jason Andryuk
@ 2025-08-27 15:21 ` Jürgen Groß
2025-08-27 22:11 ` Jason Andryuk
0 siblings, 1 reply; 10+ messages in thread
From: Jürgen Groß @ 2025-08-27 15:21 UTC (permalink / raw)
To: Jason Andryuk, Stefano Stabellini, Oleksandr Tyshchenko
Cc: xen-devel, linux-kernel
[-- Attachment #1.1.1: Type: text/plain, Size: 2766 bytes --]
On 26.08.25 02:55, Jason Andryuk wrote:
> 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.
>
> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
> ---
> V2:
> New
> ---
> drivers/xen/events/events_base.c | 17 ++++++++++++-----
> 1 file changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
> index 199afe59f357..a85bc43f4344 100644
> --- a/drivers/xen/events/events_base.c
> +++ b/drivers/xen/events/events_base.c
> @@ -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;
> int rc;
>
> memset(&status, 0, sizeof(status));
> @@ -1329,12 +1331,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;
> }
>
> /**
> @@ -1381,8 +1387,9 @@ 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)
> + goto out;
I think you are leaking info here. I guess a call of __unbind_from_irq() is
wanted like in the error case below (note that the case of no valid evtchn is
handled there just fine).
Juergen
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 3/3] xen/events: Update virq_to_irq on migration
2025-08-26 0:55 ` [PATCH v2 3/3] xen/events: Update virq_to_irq on migration Jason Andryuk
@ 2025-08-27 15:28 ` Jürgen Groß
0 siblings, 0 replies; 10+ messages in thread
From: Jürgen Groß @ 2025-08-27 15:28 UTC (permalink / raw)
To: Jason Andryuk, Stefano Stabellini, Oleksandr Tyshchenko,
Chris Wright, Jeremy Fitzhardinge
Cc: stable, xen-devel, linux-kernel
[-- Attachment #1.1.1: Type: text/plain, Size: 2470 bytes --]
On 26.08.25 02:55, Jason Andryuk wrote:
> VIRQs come in 3 flavors, per-VPU, per-domain, and global, and the VIRQs
> are tracked in per-cpu virq_to_irq arrays.
>
> Per-domain and global VIRQs must be bound on CPU 0, and
> bind_virq_to_irq() sets the per_cpu virq_to_irq at registration time
> Later, the interrupt can migrate, and info->cpu is updated. When
> calling __unbind_from_irq(), the per-cpu virq_to_irq is cleared for a
> different cpu. If bind_virq_to_irq() is called again with CPU 0, the
> stale irq is returned. There won't be any irq_info for the irq, so
> things break.
>
> Make xen_rebind_evtchn_to_cpu() update the per_cpu virq_to_irq mappings
> to keep them update to date with the current cpu. This ensures the
> correct virq_to_irq is cleared in __unbind_from_irq().
>
> Fixes: e46cdb66c8fc ("xen: event channels")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
> ---
> V2:
> Different approach changing virq_to_irq
> ---
> drivers/xen/events/events_base.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
> index a85bc43f4344..4e9db7b92dde 100644
> --- a/drivers/xen/events/events_base.c
> +++ b/drivers/xen/events/events_base.c
> @@ -1772,6 +1772,7 @@ static int xen_rebind_evtchn_to_cpu(struct irq_info *info, unsigned int tcpu)
> {
> struct evtchn_bind_vcpu bind_vcpu;
> evtchn_port_t evtchn = info ? info->evtchn : 0;
> + int old_cpu = info ? info->cpu : tcpu;
I'd prefer not to initialize old_cpu just here ...
>
> if (!VALID_EVTCHN(evtchn))
> return -1;
... as here info is always valid, so you can just use "old_cpu = info->cpu;"
(probably just after the hypercall).
> @@ -1795,8 +1796,18 @@ static int xen_rebind_evtchn_to_cpu(struct irq_info *info, unsigned int tcpu)
> * it, but don't do the xenlinux-level rebind in that case.
> */
> if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
> + {
Kernel style, please.
> bind_evtchn_to_cpu(info, tcpu, false);
>
> + if (info->type == IRQT_VIRQ) {
> + int virq = info->u.virq;
> + int irq = per_cpu(virq_to_irq, old_cpu)[virq];
> +
> + per_cpu(virq_to_irq, old_cpu)[virq] = -1;
> + per_cpu(virq_to_irq, tcpu)[virq] = irq;
> + }
> + }
> +
> do_unmask(info, EVT_MASK_REASON_TEMPORARY);
>
> return 0;
Juergen
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3743 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/3] xen/events: Return -EEXIST for bound VIRQs
2025-08-27 15:21 ` Jürgen Groß
@ 2025-08-27 22:11 ` Jason Andryuk
0 siblings, 0 replies; 10+ messages in thread
From: Jason Andryuk @ 2025-08-27 22:11 UTC (permalink / raw)
To: Jürgen Groß, Stefano Stabellini, Oleksandr Tyshchenko
Cc: xen-devel, linux-kernel
On 2025-08-27 11:21, Jürgen Groß wrote:
> On 26.08.25 02:55, Jason Andryuk wrote:
>> 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.
>>
>> Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
>
>> @@ -1381,8 +1387,9 @@ 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)
>> + goto out;
>
> I think you are leaking info here. I guess a call of __unbind_from_irq() is
> wanted like in the error case below (note that the case of no valid
> evtchn is
> handled there just fine).
Ok, thanks for catching that.
I'm going to add Cc: stable to the next version of this. While it
doesn't have a Fixes associated, we want this as a prerequisite for patch 3.
Regards,
Jason
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-08-28 0:31 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-26 0:55 [PATCH v2 0/3] xen/events: Fix Global and Domain VIRQ tracking Jason Andryuk
2025-08-26 0:55 ` [PATCH v2 1/3] xen/events: Cleanup find_virq() return codes Jason Andryuk
2025-08-26 7:22 ` Jan Beulich
2025-08-26 15:03 ` Jason Andryuk
2025-08-27 15:16 ` Jürgen Groß
2025-08-26 0:55 ` [PATCH v2 2/3] xen/events: Return -EEXIST for bound VIRQs Jason Andryuk
2025-08-27 15:21 ` Jürgen Groß
2025-08-27 22:11 ` Jason Andryuk
2025-08-26 0:55 ` [PATCH v2 3/3] xen/events: Update virq_to_irq on migration Jason Andryuk
2025-08-27 15:28 ` Jürgen Groß
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).