xen/arch/arm/include/asm/event.h | 4 ++-- xen/arch/ppc/include/asm/event.h | 4 ++-- xen/arch/riscv/include/asm/event.h | 4 ++-- xen/arch/x86/include/asm/event.h | 6 +++--- xen/common/event_channel.c | 34 +++++++++++++++++------------- xen/include/xen/sched.h | 6 ++++++ 6 files changed, 34 insertions(+), 24 deletions(-)
VIRQs are split into "global" and "per vcpu" ones. Unfortunately in
reality there are "per domain" ones, too.
send_global_virq() and set_global_virq_handler() make only sense for
the real "global" ones, so replace virq_is_global() with a new
function get_virq_type() returning one of the 3 possible types (global,
domain, vcpu VIRQ).
Fixes: 980822c5edd1 ("xen/events: allow setting of global virq handler only for unbound virqs")
Signed-off-by: Juergen Gross <jgross@suse.com>
---
As I don't have much time today (I'm having a day off), only compile
tested. Please try a CI run with this patch before applying!
xen/arch/arm/include/asm/event.h | 4 ++--
xen/arch/ppc/include/asm/event.h | 4 ++--
xen/arch/riscv/include/asm/event.h | 4 ++--
xen/arch/x86/include/asm/event.h | 6 +++---
xen/common/event_channel.c | 34 +++++++++++++++++-------------
xen/include/xen/sched.h | 6 ++++++
6 files changed, 34 insertions(+), 24 deletions(-)
diff --git a/xen/arch/arm/include/asm/event.h b/xen/arch/arm/include/asm/event.h
index b14c166ad6..509157b2b3 100644
--- a/xen/arch/arm/include/asm/event.h
+++ b/xen/arch/arm/include/asm/event.h
@@ -47,9 +47,9 @@ static inline void local_event_delivery_enable(void)
}
/* No arch specific virq definition now. Default to global. */
-static inline bool arch_virq_is_global(unsigned int virq)
+static inline enum virq_type arch_get_virq_type(unsigned int virq)
{
- return true;
+ return VIRQ_GLOBAL;
}
#endif
diff --git a/xen/arch/ppc/include/asm/event.h b/xen/arch/ppc/include/asm/event.h
index 1b95ee4f61..0f475c4b89 100644
--- a/xen/arch/ppc/include/asm/event.h
+++ b/xen/arch/ppc/include/asm/event.h
@@ -17,9 +17,9 @@ static inline int vcpu_event_delivery_is_enabled(struct vcpu *v)
}
/* No arch specific virq definition now. Default to global. */
-static inline bool arch_virq_is_global(unsigned int virq)
+static inline enum virq_type arch_get_virq_type(unsigned int virq)
{
- return true;
+ return VIRQ_GLOBAL;
}
static inline int local_events_need_delivery(void)
diff --git a/xen/arch/riscv/include/asm/event.h b/xen/arch/riscv/include/asm/event.h
index c7bb8c0fa6..116434c665 100644
--- a/xen/arch/riscv/include/asm/event.h
+++ b/xen/arch/riscv/include/asm/event.h
@@ -24,9 +24,9 @@ static inline void local_event_delivery_enable(void)
}
/* No arch specific virq definition now. Default to global. */
-static inline bool arch_virq_is_global(unsigned int virq)
+static inline enum virq_type arch_get_virq_type(unsigned int virq)
{
- return true;
+ return VIRQ_GLOBAL;
}
#endif /* ASM__RISCV__EVENT_H */
diff --git a/xen/arch/x86/include/asm/event.h b/xen/arch/x86/include/asm/event.h
index 5e09ede6d7..434f65007e 100644
--- a/xen/arch/x86/include/asm/event.h
+++ b/xen/arch/x86/include/asm/event.h
@@ -41,10 +41,10 @@ static inline void local_event_delivery_enable(void)
vcpu_info(current, evtchn_upcall_mask) = 0;
}
-/* No arch specific virq definition now. Default to global. */
-static inline bool arch_virq_is_global(unsigned int virq)
+/* Only global arch specific virq definitions. */
+static inline enum virq_type arch_get_virq_type(unsigned int virq)
{
- return true;
+ return VIRQ_GLOBAL;
}
#ifdef CONFIG_PV_SHIM
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index c68aa97135..0fcdec8a40 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -127,7 +127,7 @@ static struct domain *get_global_virq_handler(unsigned int virq)
return global_virq_handlers[virq] ?: hardware_domain;
}
-static bool virq_is_global(unsigned int virq)
+static enum virq_type get_virq_type(unsigned int virq)
{
switch ( virq )
{
@@ -135,14 +135,17 @@ static bool virq_is_global(unsigned int virq)
case VIRQ_DEBUG:
case VIRQ_XENOPROF:
case VIRQ_XENPMU:
- return false;
+ return VIRQ_VCPU;
+
+ case VIRQ_ARGO:
+ return VIRQ_DOMAIN;
case VIRQ_ARCH_0 ... VIRQ_ARCH_7:
- return arch_virq_is_global(virq);
+ return arch_get_virq_type(virq);
}
ASSERT(virq < NR_VIRQS);
- return true;
+ return VIRQ_GLOBAL;
}
static struct evtchn *_evtchn_from_port(const struct domain *d,
@@ -476,7 +479,7 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
struct domain *d = current->domain;
int virq = bind->virq, vcpu = bind->vcpu;
int rc = 0;
- bool is_global;
+ enum virq_type type;
if ( (virq < 0) || (virq >= ARRAY_SIZE(v->virq_to_evtchn)) )
return -EINVAL;
@@ -486,9 +489,9 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
* speculative execution.
*/
virq = array_index_nospec(virq, ARRAY_SIZE(v->virq_to_evtchn));
- is_global = virq_is_global(virq);
+ type = get_virq_type(virq);
- if ( is_global && vcpu != 0 )
+ if ( type != VIRQ_VCPU && vcpu != 0 )
return -EINVAL;
if ( (v = domain_vcpu(d, vcpu)) == NULL )
@@ -496,7 +499,7 @@ int evtchn_bind_virq(evtchn_bind_virq_t *bind, evtchn_port_t port)
write_lock(&d->event_lock);
- if ( is_global && get_global_virq_handler(virq) != d )
+ if ( type == VIRQ_GLOBAL && get_global_virq_handler(virq) != d )
{
rc = -EBUSY;
goto out;
@@ -756,7 +759,8 @@ int evtchn_close(struct domain *d1, int port1, bool guest)
if ( chn1->u.virq == VIRQ_DOM_EXC )
domain_deinit_states(d1);
- v = d1->vcpu[virq_is_global(chn1->u.virq) ? 0 : chn1->notify_vcpu_id];
+ v = d1->vcpu[get_virq_type(chn1->u.virq) != VIRQ_VCPU
+ ? 0 : chn1->notify_vcpu_id];
write_lock_irqsave(&v->virq_lock, flags);
ASSERT(read_atomic(&v->virq_to_evtchn[chn1->u.virq]) == port1);
@@ -900,7 +904,7 @@ bool evtchn_virq_enabled(const struct vcpu *v, unsigned int virq)
if ( !v )
return false;
- if ( virq_is_global(virq) && v->vcpu_id )
+ if ( get_virq_type(virq) != VIRQ_VCPU && v->vcpu_id )
v = domain_vcpu(v->domain, 0);
return read_atomic(&v->virq_to_evtchn[virq]);
@@ -913,7 +917,7 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq)
struct domain *d;
struct evtchn *chn;
- ASSERT(!virq_is_global(virq));
+ ASSERT(get_virq_type(virq) == VIRQ_VCPU);
read_lock_irqsave(&v->virq_lock, flags);
@@ -940,7 +944,7 @@ void send_guest_global_virq(struct domain *d, uint32_t virq)
struct vcpu *v;
struct evtchn *chn;
- ASSERT(virq_is_global(virq));
+ ASSERT(get_virq_type(virq) != VIRQ_VCPU);
if ( unlikely(d == NULL) || unlikely(d->vcpu == NULL) )
return;
@@ -995,7 +999,7 @@ static DEFINE_SPINLOCK(global_virq_handlers_lock);
void send_global_virq(uint32_t virq)
{
- ASSERT(virq_is_global(virq));
+ ASSERT(get_virq_type(virq) == VIRQ_GLOBAL);
send_guest_global_virq(get_global_virq_handler(virq), virq);
}
@@ -1008,7 +1012,7 @@ int set_global_virq_handler(struct domain *d, uint32_t virq)
if (virq >= NR_VIRQS)
return -EINVAL;
- if (!virq_is_global(virq))
+ if (get_virq_type(virq) != VIRQ_GLOBAL)
return -EINVAL;
if (global_virq_handlers[virq] == d)
@@ -1204,7 +1208,7 @@ int evtchn_bind_vcpu(evtchn_port_t port, unsigned int vcpu_id)
switch ( chn->state )
{
case ECS_VIRQ:
- if ( virq_is_global(chn->u.virq) )
+ if ( get_virq_type(chn->u.virq) != VIRQ_VCPU )
chn->notify_vcpu_id = v->vcpu_id;
else
rc = -EINVAL;
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index ea63ca1c79..43bc4da0e2 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -84,6 +84,12 @@ extern domid_t hardware_domid;
#define XEN_CONSUMER_BITS 3
#define NR_XEN_CONSUMERS ((1 << XEN_CONSUMER_BITS) - 1)
+enum virq_type {
+ VIRQ_GLOBAL,
+ VIRQ_DOMAIN,
+ VIRQ_VCPU
+};
+
struct evtchn
{
rwlock_t lock;
--
2.43.0
On 07.03.2025 08:05, Juergen Gross wrote: > @@ -913,7 +917,7 @@ void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq) > struct domain *d; > struct evtchn *chn; > > - ASSERT(!virq_is_global(virq)); > + ASSERT(get_virq_type(virq) == VIRQ_VCPU); > > read_lock_irqsave(&v->virq_lock, flags); To better fit with this function's name, ... > @@ -940,7 +944,7 @@ void send_guest_global_virq(struct domain *d, uint32_t virq) > struct vcpu *v; > struct evtchn *chn; > > - ASSERT(virq_is_global(virq)); > + ASSERT(get_virq_type(virq) != VIRQ_VCPU); > > if ( unlikely(d == NULL) || unlikely(d->vcpu == NULL) ) > return; ... I think this function wants renaming to send_guest_domain_virq(), to further eliminate underlying confusion. Ideally right here, but certainly also possible in a follow-on patch. Everything else looks okay to me. Jan
© 2016 - 2025 Red Hat, Inc.