Some UEFI implementations for ARM64 devices apply strict permissions on the different allocation types. In these implementations, DATA allocations have XN (execute never) permissions, preventing code execution from those pages.
On these implementations, the Linux kernel is loaded to DATA pages, which causes a permission fault when GRUB attempts to kick off the kernel. This results in a device crash. Fix this by allocating CODE pages for the Linux kernel. Signed-off-by: Jeffrey Hugo <jeffrey.l.h...@gmail.com> --- grub-core/kern/efi/mm.c | 8 ++++++++ grub-core/loader/arm64/linux.c | 2 +- include/grub/efi/efi.h | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index b02fab1b1..725695e01 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c @@ -156,6 +156,14 @@ grub_efi_allocate_any_pages (grub_efi_uintn_t pages) GRUB_EFI_LOADER_DATA); } +void * +grub_efi_allocate_code_pages (grub_efi_uintn_t pages) +{ + return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, + pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_LOADER_CODE); +} + void * grub_efi_allocate_fixed (grub_efi_physical_address_t address, grub_efi_uintn_t pages) diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c index ef3e9f944..877839072 100644 --- a/grub-core/loader/arm64/linux.c +++ b/grub-core/loader/arm64/linux.c @@ -313,7 +313,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_loader_unset(); grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size); - kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + kernel_addr = grub_efi_allocate_code_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size)); grub_dprintf ("linux", "kernel numpages: %lld\n", (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size)); if (!kernel_addr) diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index e90e00dc4..697cabcd6 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -47,6 +47,8 @@ EXPORT_FUNC(grub_efi_allocate_fixed) (grub_efi_physical_address_t address, grub_efi_uintn_t pages); void * EXPORT_FUNC(grub_efi_allocate_any_pages) (grub_efi_uintn_t pages); +void * +EXPORT_FUNC(grub_efi_allocate_code_pages) (grub_efi_uintn_t pages); void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, grub_efi_uintn_t pages); grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void); -- 2.17.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel