Arch level code is ready to take over the nmi_enter()/nmi_exit() housekeeping. GICv3 can expose the pNMI discriminator, then simply remove the housekeeping. Signed-off-by: Pingfan Liu <kernelfans@xxxxxxxxx> Cc: Catalin Marinas <catalin.marinas@xxxxxxx> Cc: Will Deacon <will@xxxxxxxxxx> Cc: Mark Rutland <mark.rutland@xxxxxxx> Cc: Marc Zyngier <maz@xxxxxxxxxx> Cc: Joey Gouly <joey.gouly@xxxxxxx> Cc: Sami Tolvanen <samitolvanen@xxxxxxxxxx> Cc: Julien Thierry <julien.thierry@xxxxxxx> Cc: Yuichi Ito <ito-yuichi@xxxxxxxxxxx> Cc: rcu@xxxxxxxxxxxxxxx To: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx --- drivers/irqchip/irq-gic-v3.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index daec3309b014..aa2bcb47b47e 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -646,12 +646,8 @@ static void gic_deactivate_unhandled(u32 irqnr) static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs) { - bool irqs_enabled = interrupts_enabled(regs); int err; - if (irqs_enabled) - nmi_enter(); - if (static_branch_likely(&supports_deactivate_key)) gic_write_eoir(irqnr); /* @@ -664,8 +660,6 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs) if (err) gic_deactivate_unhandled(irqnr); - if (irqs_enabled) - nmi_exit(); } static u32 do_read_iar(struct pt_regs *regs) @@ -702,6 +696,15 @@ static u32 do_read_iar(struct pt_regs *regs) return iar; } +static bool gic_is_in_nmi(void) +{ + if (gic_supports_nmi() && + unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI))) + return true; + + return false; +} + static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) { u32 irqnr; @@ -1791,6 +1794,9 @@ static int __init gic_init_bases(void __iomem *dist_base, } set_handle_irq(gic_handle_irq); +#if IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) + set_nmi_discriminator(gic_is_in_nmi); +#endif gic_update_rdist_properties(); -- 2.31.1