[RFC 07/12] riscv: Handle pseudo NMI in arch irq handler
Xu Lu
luxu.kernel at bytedance.com
Mon Oct 23 01:29:06 PDT 2023
This commit handles pseudo NMI in arch irq handler. We enter NMI context
before handling NMI and keeps all interrupts disabled during NMI handling
to avoid interrupt nesting.
Signed-off-by: Xu Lu <luxu.kernel at bytedance.com>
Signed-off-by: Hangjing Li <lihangjing at bytedance.com>
---
drivers/irqchip/irq-riscv-intc.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
index 83a0a744fce6..c672c0c64d5d 100644
--- a/drivers/irqchip/irq-riscv-intc.c
+++ b/drivers/irqchip/irq-riscv-intc.c
@@ -20,6 +20,26 @@
static struct irq_domain *intc_domain;
+#ifdef CONFIG_RISCV_PSEUDO_NMI
+
+static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
+{
+ unsigned long cause = regs->cause & ~CAUSE_IRQ_FLAG;
+
+ if (unlikely(cause >= BITS_PER_LONG))
+ panic("unexpected interrupt cause");
+
+ if (is_nmi(cause)) {
+ nmi_enter();
+ generic_handle_domain_nmi(intc_domain, cause);
+ nmi_exit();
+ } else {
+ generic_handle_domain_irq(intc_domain, cause);
+ }
+}
+
+#else /* CONFIG_RISCV_PSEUDO_NMI */
+
static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
{
unsigned long cause = regs->cause & ~CAUSE_IRQ_FLAG;
@@ -30,6 +50,8 @@ static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
generic_handle_domain_irq(intc_domain, cause);
}
+#endif /* CONFIG_RISCV_PSEUDO_NMI */
+
/*
* On RISC-V systems local interrupts are masked or unmasked by writing
* the SIE (Supervisor Interrupt Enable) CSR. As CSRs can only be written
--
2.20.1
More information about the linux-riscv
mailing list