]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
arm64/efi: Move uaccess en/disable out of efi_set_pgd()
authorArd Biesheuvel <ardb@kernel.org>
Wed, 15 Oct 2025 20:56:41 +0000 (22:56 +0200)
committerCatalin Marinas <catalin.marinas@arm.com>
Tue, 11 Nov 2025 18:59:22 +0000 (18:59 +0000)
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.

Acked-by: Will Deacon <will@kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/efi.h
arch/arm64/kernel/efi.c

index bcd5622aa09686a9d256af624b2a92abc3e6fee0..aa91165ca14071f0b280c6d04c44cda47a1e4e17 100644 (file)
@@ -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);
                }
        }
index 0094f5938ba618ab785fd11765f61fd503b99cfb..85f65d5c863c5589177767b3f7d6ec2d26bd3796 100644 (file)
@@ -169,12 +169,30 @@ void arch_efi_call_virt_setup(void)
 {
        efi_runtime_assert_lock_held();
        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();
 }
 
 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();
 }