[RFC,07/12] riscv: Handle pseudo NMI in arch irq handler

Message ID 20231023082911.23242-8-luxu.kernel@bytedance.com
State New
Headers
Series riscv: Introduce Pseudo NMI |

Commit Message

Xu Lu Oct. 23, 2023, 8:29 a.m. UTC
  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@bytedance.com>
Signed-off-by: Hangjing Li <lihangjing@bytedance.com>
---
 drivers/irqchip/irq-riscv-intc.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
  

Patch

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