Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

efi/arm: Disable LPAE PAN when calling EFI runtime services

EFI runtime services are remapped into the lower 1 GiB of virtual
address space at boot, so they are guaranteed to be able to co-exist
with the kernel virtual mappings without the need to allocate space for
them in the kernel's vmalloc region, which is rather small.

This means those mappings are covered by TTBR0 when LPAE PAN is enabled,
and so 'user' access must be enabled while such calls are in progress.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

+13
+13
arch/arm/include/asm/efi.h
··· 14 14 #include <asm/mach/map.h> 15 15 #include <asm/mmu_context.h> 16 16 #include <asm/ptrace.h> 17 + #include <asm/uaccess.h> 17 18 18 19 #ifdef CONFIG_EFI 19 20 void efi_init(void); ··· 25 24 26 25 #define arch_efi_call_virt_setup() efi_virtmap_load() 27 26 #define arch_efi_call_virt_teardown() efi_virtmap_unload() 27 + 28 + #ifdef CONFIG_CPU_TTBR0_PAN 29 + #undef arch_efi_call_virt 30 + #define arch_efi_call_virt(p, f, args...) ({ \ 31 + unsigned int flags = uaccess_save_and_enable(); \ 32 + efi_status_t res = _Generic((p)->f(args), \ 33 + efi_status_t: (p)->f(args), \ 34 + default: ((p)->f(args), EFI_ABORTED)); \ 35 + uaccess_restore(flags); \ 36 + res; \ 37 + }) 38 + #endif 28 39 29 40 #define ARCH_EFI_IRQ_FLAGS_MASK \ 30 41 (PSR_J_BIT | PSR_E_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | \