[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] xen/riscv: implement setup_irq()
commit 0aa91c3cd593f1f835a976d63777b088a0acc800 Author: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx> AuthorDate: Thu Jul 10 13:40:42 2025 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Thu Jul 10 13:40:42 2025 +0200 xen/riscv: implement setup_irq() Introduce support for IRQ setup on RISC-V by implementing setup_irq() and __setup_irq(), adapted and extended from an initial implementation by [1]. __setup_irq() does the following: - Sets up an IRQ action. - Validates that shared IRQs have non-NULL `dev_id` and are only used when existing handlers allow sharing. - Uses smp_wmb() to enforce memory ordering after assigning desc->action to ensure visibility before enabling the IRQ. - Supports multi-action setups via CONFIG_IRQ_HAS_MULTIPLE_ACTION. setup_irq() does the following: - Converts IRQ number to descriptor and acquires its lock. - Rejects registration if the IRQ is already assigned to a guest domain, printing an error. - Delegates the core setup to __setup_irq(). - On first-time setup, disables the IRQ, routes it to Xen using intc_route_irq_to_xen(), sets default CPU affinity (current CPU), calls the handlerâ??s startup routine, and finally enables the IRQ. irq_set_affinity() invokes set_affinity() callback from the IRQ handler if present. Defined IRQ_NO_PRIORITY as default priority used when routing IRQs to Xen. [1] https://gitlab.com/xen-project/people/olkur/xen/-/commit/7390e2365828b83e27ead56b03114a56e3699dd5 Co-developed-by: Romain Caritey <Romain.Caritey@xxxxxxxxxxxxx> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx> Acked-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/arch/riscv/include/asm/irq.h | 2 + xen/arch/riscv/irq.c | 84 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/xen/arch/riscv/include/asm/irq.h b/xen/arch/riscv/include/asm/irq.h index 94151eb083..f633636dc3 100644 --- a/xen/arch/riscv/include/asm/irq.h +++ b/xen/arch/riscv/include/asm/irq.h @@ -17,6 +17,8 @@ */ #define NR_IRQS 1024 +#define IRQ_NO_PRIORITY 0 + /* TODO */ #define nr_irqs 0U #define nr_static_irqs 0 diff --git a/xen/arch/riscv/irq.c b/xen/arch/riscv/irq.c index 466f1b4ba9..25d3295002 100644 --- a/xen/arch/riscv/irq.c +++ b/xen/arch/riscv/irq.c @@ -7,6 +7,7 @@ */ #include <xen/bug.h> +#include <xen/cpumask.h> #include <xen/device_tree.h> #include <xen/errno.h> #include <xen/init.h> @@ -63,6 +64,89 @@ int platform_get_irq(const struct dt_device_node *device, int index) return dt_irq.irq; } +static int _setup_irq(struct irq_desc *desc, unsigned int irqflags, + struct irqaction *new) +{ + bool shared = irqflags & IRQF_SHARED; + + ASSERT(new != NULL); + + /* + * Sanity checks: + * - if the IRQ is marked as shared + * - dev_id is not NULL when IRQF_SHARED is set + */ + if ( desc->action != NULL && (!(desc->status & IRQF_SHARED) || !shared) ) + return -EINVAL; + if ( shared && new->dev_id == NULL ) + return -EINVAL; + + if ( shared ) + desc->status |= IRQF_SHARED; + +#ifdef CONFIG_IRQ_HAS_MULTIPLE_ACTION + new->next = desc->action; +#endif + + desc->action = new; + smp_wmb(); + + return 0; +} + +int setup_irq(unsigned int irq, unsigned int irqflags, struct irqaction *new) +{ + int rc; + unsigned long flags; + struct irq_desc *desc = irq_to_desc(irq); + bool disabled; + + spin_lock_irqsave(&desc->lock, flags); + + disabled = (desc->action == NULL); + + if ( desc->status & IRQ_GUEST ) + { + spin_unlock_irqrestore(&desc->lock, flags); + /* + * TODO: would be nice to have functionality to print which domain owns + * an IRQ. + */ + printk(XENLOG_ERR "ERROR: IRQ %u is already in use by a domain\n", irq); + return -EBUSY; + } + + rc = _setup_irq(desc, irqflags, new); + if ( rc ) + goto err; + + /* First time the IRQ is setup */ + if ( disabled ) + { + /* Route interrupt to xen */ + intc_route_irq_to_xen(desc, IRQ_NO_PRIORITY); + + /* + * We don't care for now which CPU will receive the + * interrupt. + * + * TODO: Handle case where IRQ is setup on different CPU than + * the targeted CPU and the priority. + */ + desc->handler->set_affinity(desc, cpumask_of(smp_processor_id())); + + desc->handler->startup(desc); + + /* Enable irq */ + desc->status &= ~IRQ_DISABLED; + } + + err: + spin_unlock_irqrestore(&desc->lock, flags); + + return rc; +} + int arch_init_one_irq_desc(struct irq_desc *desc) { desc->arch.type = IRQ_TYPE_INVALID; -- generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |