On 07.03.2025 11:11, Jan Beulich wrote: Sorry, missed From: Juergen Gross <jgr...@suse.com>
Jan > 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). > > To make its intended purpose more clear, also rename > send_guest_global_virq() to send_guest_domain_virq(). > > Fixes: 980822c5edd1 ("xen/events: allow setting of global virq handler only > for unbound virqs") > Signed-off-by: Juergen Gross <jgr...@suse.com> > Signed-off-by: Jan Beulich <jbeul...@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! > > Whether the "domain" infix in send_guest_domain_virq() is really useful > I don't know. Maybe we should go even father with renaming, to have > {vcpu,domain}_send_virq()? > --- > v2: Also rename send_guest_global_virq(). > > --- 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_ > } > > /* 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 > --- 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 > } > > /* 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) > --- 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_ > } > > /* 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 */ > --- 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_ > 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 > --- a/xen/common/argo.c > +++ b/xen/common/argo.c > @@ -440,7 +440,7 @@ signal_domain(struct domain *d) > { > argo_dprintk("signalling domid:%u\n", d->domain_id); > > - send_guest_global_virq(d, VIRQ_ARGO); > + send_guest_domain_virq(d, VIRQ_ARGO); > } > > static void > --- a/xen/common/event_channel.c > +++ b/xen/common/event_channel.c > @@ -127,7 +127,7 @@ static struct domain *get_global_virq_ha > 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 > 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 > 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 > * 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 > > 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 > 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 vc > 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 > 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); > > @@ -933,14 +937,14 @@ void send_guest_vcpu_virq(struct vcpu *v > read_unlock_irqrestore(&v->virq_lock, flags); > } > > -void send_guest_global_virq(struct domain *d, uint32_t virq) > +void send_guest_domain_virq(struct domain *d, uint32_t virq) > { > unsigned long flags; > int port; > 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,9 +999,9 @@ static DEFINE_SPINLOCK(global_virq_handl > > 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); > + send_guest_domain_virq(get_global_virq_handler(virq), virq); > } > > int set_global_virq_handler(struct domain *d, uint32_t virq) > @@ -1008,7 +1012,7 @@ int set_global_virq_handler(struct domai > > 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, > 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; > --- a/xen/include/xen/event.h > +++ b/xen/include/xen/event.h > @@ -24,17 +24,17 @@ > void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq); > > /* > - * send_global_virq: Notify the domain handling a global VIRQ. > - * @virq: Virtual IRQ number (VIRQ_*) > + * send_guest_domain_virq: > + * @d: Domain to which VIRQ should be sent > + * @virq: Virtual IRQ number (VIRQ_*), may not be per-vCPU > */ > -void send_global_virq(uint32_t virq); > +void send_guest_domain_virq(struct domain *d, uint32_t virq); > > /* > - * send_guest_global_virq: > - * @d: Domain to which VIRQ should be sent > - * @virq: Virtual IRQ number (VIRQ_*), must be global > + * send_global_virq: Notify the domain handling a global VIRQ. > + * @virq: Virtual IRQ number (VIRQ_*) > */ > -void send_guest_global_virq(struct domain *d, uint32_t virq); > +void send_global_virq(uint32_t virq); > > /* > * sent_global_virq_handler: Set a global VIRQ handler. > --- 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;