[RFC PATCH v2 17/45] arm64: interrupts: introduce a helper for GIC priority initialization
Jinjie Ruan
ruanjinjie at huawei.com
Tue Jul 28 04:21:37 PDT 2026
在 2026/7/28 0:34, Vladimir Murzin 写道:
> From: Ada Couprie Diaz <ada.coupriediaz at arm.com>
>
> 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 <ada.coupriediaz at arm.com>
> Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
> ---
> 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();
Reviewed-by: Jinjie Ruan <ruanjinjie at huawei.com>
> }
>
> #ifdef CONFIG_DEBUG_IRQFLAGS
More information about the linux-arm-kernel
mailing list