grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC] arm64/linux/loader: Use EFI CODE allocations for the linux kernel


From: Jeffrey Hugo
Subject: [RFC] arm64/linux/loader: Use EFI CODE allocations for the linux kernel
Date: Thu, 4 Apr 2019 07:54:55 -0700

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 <address@hidden>
---
 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]