The code portions of a loaded UEFI application.
Paging mode is enabled and any memory space defined by the UEFI memory
map is identity mapped (virtual address equals physical address),
although the attributes of certain regions may not have all read,
write, and execute attributes or be unmarked for purposes of platform
protection.
On Wed, 10 Nov 2021 at 11:56, Baskov Evgeniy <baskov@xxxxxxxxx> wrote:
Note, that this patch series is RFC, since it is yet untested
and possibly incompatible with AMD SEV and related extensions.
The UEFI specification states that certain memory regions may
not have every permission, i.e. may not be writable or executable.
Furthermore there exist some implementations (at least on i386/x86_64)
that restrict execution of memory regions expected by the kernel to
be executable. E.g. first megabyte of address space, where trampoline
for switching between 4/5 level paging is placed and memory regions,
allocated as loader data.
This patch series allows Linux kernel to boot on such UEFI
implementations on i386 and x86_64.
The simplest way to achieve that on i386 is to disable paging
before jumping to potentially relocated code.
x86_64, on the other hand, does not allow disabling paging so it
is required to build temporary page tables containing memory regions
required for Linux kernel to boot with appropriate access permissions.
Hello Baskov,
To be honest, I am truly not a fan of this approach.
Which systems is this issue occurring on? Did you try something like
the below to allocate executable memory explicitly?
diff --git a/drivers/firmware/efi/libstub/relocate.c
b/drivers/firmware/efi/libstub/relocate.c
index 8ee9eb2b9039..b73012a7bcdc 100644
--- a/drivers/firmware/efi/libstub/relocate.c
+++ b/drivers/firmware/efi/libstub/relocate.c
@@ -80,7 +80,7 @@ efi_status_t efi_low_alloc_above(unsigned long size,
unsigned long align,
continue;
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
- EFI_LOADER_DATA, nr_pages, &start);
+ EFI_LOADER_CODE, nr_pages, &start);
if (status == EFI_SUCCESS) {
*addr = start;
break;
@@ -146,7 +146,7 @@ efi_status_t efi_relocate_kernel(unsigned long *image_addr,
*/
nr_pages = round_up(alloc_size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
- EFI_LOADER_DATA, nr_pages, &efi_addr);
+ EFI_LOADER_CODE, nr_pages, &efi_addr);
new_addr = efi_addr;
/*
* If preferred address allocation failed allocate as low as