UEFI stub pre-boot compat checks
cover UEFI stub pre-boot compat checks
As discussed earlier today [1], and last year [2], it makes sense for the UEFI stub to perform some basic checks on the hardware for missing features that would prevent the kernel from booting to a state where it can even complain about this.
So implements this for ARM, to check on LPAE builds whether the CPU supports it (patch #1), and for arm64, to check whether the build time granule is implemented by the CPU (patch #2). Patch #3 wires it up into the shared init code.
[1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/472880
[2] http://thread.gmane.org/gmane.linux.ports.arm.kernel/447370
Ard Biesheuvel (3):
ARM: efistub: check for LPAE support before booting a LPAE kernel
arm64: efistub: check for h/w support before booting a >4 KB granule
kernel
ARM/arm64: efistub: perform hardware compatibility check
drivers/firmware/efi/libstub/arm-stub.c | 4 ++++ drivers/firmware/efi/libstub/arm32-stub.c | 17 +++++++++++++++++ drivers/firmware/efi/libstub/arm64-stub.c | 20 ++++++++++++++++++++ drivers/firmware/efi/libstub/efistub.h | 2 ++ 4 files changed, 43 insertions(+)
Signature · 1 line
2.5.0
PATCH 1/3 ARM: efistub: check for LPAE support before booting a LPAE kernel
A kernel built with support for LPAE cannot boot to a state where it can inform the user about it if it fails due to missing LPAE support in the hardware.
If we happen to be booting via UEFI, we can fail gracefully so check for LPAE support in the hardware on CONFIG_ARM_LPAE builds before entering the kernel proper.
--- drivers/firmware/efi/libstub/arm32-stub.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
drivers/firmware/efi/libstub/arm32-stub.c +17 -0
@@ -9,6 +9,23 @@#include <linux/efi.h> #include <asm/efi.h> +efi_status_t check_platform_features (efi_system_table_t *sys_table_arg) +{ +int block; + +/* non-LPAE kernels can run anywhere */ +if (!IS_ENABLED (CONFIG_ARM_LPAE )) +return EFI_SUCCESS ; + +/* LPAE kernels need compatible hardware */ + block =cpuid_feature_extract (CPUID_EXT_MMFR0 ,0 ); +if (block <5 ) { +pr_efi_err (sys_table_arg,"This LPAE kernel is not supported by your CPU\n" ); +return EFI_UNSUPPORTED ; + } +return EFI_SUCCESS ; +} + efi_status_t handle_kernel_image(efi_system_table_t *sys_table, unsigned long *image_addr, unsigned long *image_size,
Signature · 1 line
2.5.0
PATCH 2/3 arm64: efistub: check for h/w support before booting a >4 KB granule kernel
In reply to Ard BiesheuvelA kernel built with support for a page size that is not supported by the hardware it runs on cannot boot to a state where it can inform the user about it.
If we happen to be booting via UEFI, we can fail gracefully so check if the currently configured page size is supported by the hardware before entering the kernel proper. Note that UEFI mandates support for 4 KB pages, so in that case, no check is needed.
--- drivers/firmware/efi/libstub/arm64-stub.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
drivers/firmware/efi/libstub/arm64-stub.c +20 -0
@@ -12,6 +12,26 @@#include <linux/efi.h> #include <asm/efi.h> #include <asm/sections.h> +#include <asm/sysreg.h> + +efi_status_t check_platform_features (efi_system_table_t *sys_table_arg) +{ +u64 tg; + +/* UEFI mandates support for 4 KB granule, no need to check */ +if (IS_ENABLED (CONFIG_ARM64_4K_PAGES )) +return EFI_SUCCESS ; + + tg = (read_cpuid (ID_AA64MMFR0_EL1 ) >>ID_AA64MMFR0_TGRAN_SHIFT ) &0xf ; +if (tg !=ID_AA64MMFR0_TGRAN_SUPPORTED ) { +if (IS_ENABLED (CONFIG_ARM64_64K_PAGES )) +pr_efi_err (sys_table_arg,"This 64 KB granule kernel is not supported by your CPU\n" ); +else +pr_efi_err (sys_table_arg,"This 16 KB granule kernel is not supported by your CPU\n" ); +return EFI_UNSUPPORTED ; + } +return EFI_SUCCESS ; +} efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg, unsigned long *image_addr,
Signature · 1 line
2.5.0
PATCH 3/3 ARM/arm64: efistub: perform hardware compatibility check
In reply to Ard BiesheuvelBefore proceeding with relocating the kernel and parsing the command line, insert a call to check_platform_features() to allow an arch specific check to be performed whether the current kernel can execute on the current hardware.
--- drivers/firmware/efi/libstub/arm-stub.c | 4 ++++ drivers/firmware/efi/libstub/efistub.h | 2 ++ 2 files changed, 6 insertions(+)
drivers/firmware/efi/libstub/arm-stub.c +4 -0
@@ -190,6 +190,10 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,pr_efi (sys_table,"Booting Linux Kernel...\n" ); + status =check_platform_features (sys_table); +if (status !=EFI_SUCCESS ) + goto fail; +/* * Get a handle to the loaded image protocol. This is used to get * information about the running image, such as size and the command
drivers/firmware/efi/libstub/efistub.h +2 -0
@@ -43,4 +43,6 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, unsigned long desc_size, efi_memory_desc_t *runtime_map, int *count); +efi_status_t check_platform_features (efi_system_table_t *sys_table_arg); +#endif
Signature · 1 line
2.5.0
cover UEFI stub pre-boot compat checks
In reply to Ard BiesheuvelQuoted 5 lines · Ard Biesheuvel
As discussed earlier today [1], and last year [2], it makes sense for the UEFI stub to perform some basic checks on the hardware for missing features that would prevent the kernel from booting to a state where it can even complain about this.
Quoted 7 lines
So implements this for ARM, to check on LPAE builds whether the CPU supports it (patch #1), and for arm64, to check whether the build time granule is implemented by the CPU (patch #2). Patch #3 wires it up into the shared init code.
[1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/472880
[2] http://thread.gmane.org/gmane.linux.ports.arm.kernel/447370
Ard,
Thanks for the quick solution. I tested this on Juno for 16K granule. So, for arm64:
Cheers
Suzuki
cover UEFI stub pre-boot compat checks
In reply to Ard BiesheuvelQuoted 9 lines · Ard Biesheuvel
As discussed earlier today [1], and last year [2], it makes sense for the UEFI stub to perform some basic checks on the hardware for missing features that would prevent the kernel from booting to a state where it can even complain about this.
So implements this for ARM, to check on LPAE builds whether the CPU supports it (patch #1), and for arm64, to check whether the build time granule is implemented by the CPU (patch #2). Patch #3 wires it up into the shared init code.
Ard,
This version looks good, and addresses all the reservations from the 16k page thread. Thanks!