arm64: entry: mask DAIF before returning from C EL1 handlers

Most EL1 exceptions already call local_daif_mask() before returning,
with the exception of debug exception handlers which do not change
DAIF, and the IRQ/FIQ/Error handlers.

However, DAIF get masked in kernel_exit() in all cases when returning
from EL1 C handlers anyway.

Move this masking from assembly to C by calling local_daif_mask()
before irqentry_nmi_exit(). Unlike the raw DAIF masking helper,
local_daif_mask() invokes trace_hardirqs_off(), so it must execute
while RCU is still watching.

Remove the disable_daif assembly macro, as this was its only use.

Signed-off-by: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com>
Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
Ada Couprie Diaz 2026-07-27 17:34:15 +01:00 committed by Will Deacon
parent d3ebdc1772
commit 0d774e0517
3 changed files with 2 additions and 8 deletions

View File

@ -34,10 +34,6 @@
wx\n .req w\n
.endr
.macro disable_daif
msr daifset, #0xf
.endm
/*
* Save/restore interrupts.
*/

View File

@ -495,6 +495,7 @@ static __always_inline void __el1_pnmi(struct pt_regs *regs,
state = irqentry_nmi_enter(regs);
do_interrupt_handler(regs, handler);
local_daif_mask();
irqentry_nmi_exit(regs, state);
}
@ -540,6 +541,7 @@ asmlinkage void noinstr el1h_64_error_handler(struct pt_regs *regs)
local_daif_restore(DAIF_ERRCTX);
state = irqentry_nmi_enter(regs);
do_serror(regs, esr);
local_daif_mask();
irqentry_nmi_exit(regs, state);
}

View File

@ -333,10 +333,6 @@ alternative_else_nop_endif
.endm
.macro kernel_exit, el
.if \el != 0
disable_daif
.endif
#ifdef CONFIG_ARM64_PSEUDO_NMI
alternative_if_not ARM64_HAS_GIC_PRIO_MASKING
b .Lskip_pmr_restore\@