[RFC PATCH 23/36] arm64/efi: Implement override for IRQ flags checks

Jinjie Ruan ruanjinjie at huawei.com
Mon Jul 13 01:22:57 PDT 2026



On 7/9/2026 8:13 PM, Vladimir Murzin wrote:
> Take advantage of the recent changes to the way arm64 represents IRQ
> flags and implement an architecture-specific override for the EFI IRQ
> flags check.
> 
> IRQ flags now carry both DAIF and PMR state. EFI is not expected to
> modify either of them, so check both when verifying that IRQ state is
> preserved across EFI runtime calls.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
> ---
>  arch/arm64/include/asm/efi.h | 38 ++++++++++++++++++++++++++++++------
>  1 file changed, 32 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
> index e8a9783235cb..479741d52c90 100644
> --- a/arch/arm64/include/asm/efi.h
> +++ b/arch/arm64/include/asm/efi.h
> @@ -5,6 +5,7 @@
>  #include <asm/boot.h>
>  #include <asm/cpufeature.h>
>  #include <asm/fpsimd.h>
> +#include <asm/interrupts/common_flags.h>
>  #include <asm/io.h>
>  #include <asm/memory.h>
>  #include <asm/mmu_context.h>
> @@ -48,18 +49,43 @@ void arch_efi_call_virt_teardown(void);
>  	(efi_rt_stack_top != NULL &&					\
>  	 on_task_stack(current, READ_ONCE(efi_rt_stack_top[-1]), 1))
>  
> -#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
> -
>  /*
>   * Even when Linux uses IRQ priorities for IRQ disabling, EFI does not.
>   * And EFI shouldn't really play around with priority masking as it is not aware
>   * which priorities the OS has assigned to its interrupts.

Can this comment be deleted?

>   */
>  #define arch_efi_save_flags(state_flags)		\
> -	((void)((state_flags) = read_sysreg(daif)))
> -
> -#define arch_efi_restore_flags(state_flags)	write_sysreg(state_flags, daif)
> -
> +	((void)((state_flags) = arch_local_save_flags()))
> +
> +#define arch_efi_restore_flags(state_flags)			\
> +do {								\
> +	arm64_exc_hwstate_t __st = {.flags=state_flags};	\
> +								\
> +	arm64_update_exc_hwstate(__st, true, true);		\
> + } while(0)
> +
> +#define arch_efi_check_flags(state_flags, caller)									\
> +do {															\
> +	arm64_exc_hwstate_t __actual = {.flags =  arch_local_save_flags() };						\
> +	arm64_exc_hwstate_t __expected = {.flags=state_flags};								\
> +															\
> +	if (__expected.flags == __actual.flags)										\
> +		break;													\
> +															\
> +	add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_NOW_UNRELIABLE);							\
> +															\
> +	if (system_uses_irq_prio_masking()) {										\
> +		pr_err_ratelimited(FW_BUG "DAIF+PMR corrupted (0x%x + 0x%x=>0x%x + 0x%x) by EFI call from %pS\n",	\
> +				   __expected.daif, __expected.pmr, __actual.daif, __actual.pmr,			\
> +				   caller ?: __builtin_return_address(0));						\
> +	} else {													\
> +		pr_err_ratelimited(FW_BUG "DAIF corrupted (0x%x=>0x%x) by EFI call from %pS\n",				\
> +				   __expected.daif, __actual.daif,							\
> +				   caller ?: __builtin_return_address(0));						\
> +	}														\
> +															\
> +	arch_efi_restore_flags(state_flags);										\
> +} while(0)
>  
>  /* arch specific definitions used by the stub code */
>  




More information about the linux-arm-kernel mailing list