[RFC PATCH v2 17/45] arm64: interrupts: introduce a helper for GIC priority initialization
From: Vladimir Murzin <hidden>
Date: 2026-07-27 16:36:12
Subsystem:
arm64 port (aarch64 architecture), the rest · Maintainers:
Catalin Marinas, Will Deacon, Linus Torvalds
From: Ada Couprie Diaz <redacted> Arm64's `init_IRQ()` calls `local_daif_restore()` to synchronize interrupt masking via DAIF and switch to masking via PMR. This depends on a very specific behaviour of `local_daif_restore()` which will clear DAIF if masking interrupts via PMR, which will get removed in the future. As `setup_arch()` cleared DA only earlier, introduce a dedicated helper that explicitly initializes the PMR to mask interrupts and clears DAIF, switching to IRQ priority masking. Given it is a dedicated helper, add a lockdep assertion as `setup_arch()` should always have called `trace_hardirqs_off()` when clearing DA, otherwise something bad happened. Signed-off-by: Ada Couprie Diaz <redacted> Signed-off-by: Vladimir Murzin <redacted> --- arch/arm64/include/asm/interrupts/masking.h | 19 +++++++++++++++++++ arch/arm64/kernel/irq.c | 13 +++++-------- 2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/include/asm/interrupts/masking.h b/arch/arm64/include/asm/interrupts/masking.h
index fd4fb5497c7e..193089fda252 100644
--- a/arch/arm64/include/asm/interrupts/masking.h
+++ b/arch/arm64/include/asm/interrupts/masking.h@@ -5,6 +5,8 @@ #ifndef __ASM_INTERRUPTS_MASKING_H #define __ASM_INTERRUPTS_MASKING_H +#include <linux/lockdep.h> + #include <asm/arch_gicv3.h> #include <asm/bug.h> #include <asm/cpufeature.h>
@@ -86,4 +88,21 @@ static inline void local_exceptions_final_mask(void) __local_exceptions_final_mask(); } #endif /* CONFIG_DEBUG_IRQFLAGS */ + +/* + * During early boot, we unmask PSR.DA before the GIC has been set up. + * If we use IRQ priority masking, the PMR and PSR will be out of sync + * after the GIC is enabled : sync them up. + */ +static inline void local_interrupt_priority_init(void) +{ + if (!system_uses_irq_prio_masking()) + return; + + WARN_ON(read_sysreg(daif) & PSR_A_BIT); + lockdep_assert_irqs_disabled(); + + arm64_update_exc_context(NOIRQ_CONTEXT); +} + #endif /* __ASM_INTERRUPTS_MASKING_H */
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index ca98db345f92..a3d9128ba195 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c@@ -130,14 +130,11 @@ void __init init_IRQ(void) irqchip_init(); - if (system_uses_irq_prio_masking()) { - /* - * Now that we have a stack for our IRQ handler, set - * the PMR/PSR pair to a consistent state. - */ - WARN_ON(read_sysreg(daif) & PSR_A_BIT); - local_daif_restore(DAIF_PROCCTX_NOIRQ); - } + /* + * Now that we have a stack for our IRQ handler, + * let's mask interrupts via the PMR. + */ + local_interrupt_priority_init(); } #ifdef CONFIG_DEBUG_IRQFLAGS
--
2.34.1