[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