|
[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 |