[PATCH v2 6/7] arm64/efi: Move uaccess en/disable out of efi_set_pgd()
From: Ard Biesheuvel <hidden>
Date: 2025-09-05 13:30:55
Also in:
linux-efi, lkml
Subsystem:
arm64 port (aarch64 architecture), extensible firmware interface (efi), the rest · Maintainers:
Catalin Marinas, Will Deacon, Ard Biesheuvel, Linus Torvalds
From: Ard Biesheuvel <ardb@kernel.org> efi_set_pgd() will no longer be called when invoking EFI runtime services via the efi_rts_wq work queue, but the uaccess en/disable are still needed when using PAN emulation using TTBR0 switching. So move these into the callers. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> --- arch/arm64/include/asm/efi.h | 13 +++---------- arch/arm64/kernel/efi.c | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index decf87777f57..09650b2e15af 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h@@ -126,21 +126,14 @@ static inline void efi_set_pgd(struct mm_struct *mm) if (mm != current->active_mm) { /* * Update the current thread's saved ttbr0 since it is - * restored as part of a return from exception. Enable - * access to the valid TTBR0_EL1 and invoke the errata - * workaround directly since there is no return from - * exception when invoking the EFI run-time services. + * restored as part of a return from exception. */ update_saved_ttbr0(current, mm); - uaccess_ttbr0_enable(); - post_ttbr_update_workaround(); } else { /* - * Defer the switch to the current thread's TTBR0_EL1 - * until uaccess_enable(). Restore the current - * thread's saved ttbr0 corresponding to its active_mm + * Restore the current thread's saved ttbr0 + * corresponding to its active_mm */ - uaccess_ttbr0_disable(); update_saved_ttbr0(current, current->active_mm); } }
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 8b999c07c7d1..ece046bcf0db 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c@@ -178,6 +178,15 @@ bool arch_efi_call_virt_setup(void) return false; efi_virtmap_load(); + + /* + * Enable access to the valid TTBR0_EL1 and invoke the errata + * workaround directly since there is no return from exception when + * invoking the EFI run-time services. + */ + uaccess_ttbr0_enable(); + post_ttbr_update_workaround(); + __efi_fpsimd_begin(); return true; }
@@ -185,6 +194,15 @@ bool arch_efi_call_virt_setup(void) void arch_efi_call_virt_teardown(void) { __efi_fpsimd_end(); + + /* + * Defer the switch to the current thread's TTBR0_EL1 until + * uaccess_enable(). Do so before efi_virtmap_unload() updates the + * saved TTBR0 value, so the userland page tables are not activated + * inadvertently over the back of an exception. + */ + uaccess_ttbr0_disable(); + efi_virtmap_unload(); up(&efi_rt_lock); }
--
2.51.0.355.g5224444f11-goog