Mailing List Archive

[xen master] EFI: relocate the ESRT when booting via multiboot2
commit 8d7acf3f7d8d2555c78421dced45bc49f79ae806
Author: Demi Marie Obenour <demi@invisiblethingslab.com>
AuthorDate: Wed Dec 14 12:00:35 2022 +0100
Commit: Jan Beulich <jbeulich@suse.com>
CommitDate: Wed Dec 14 12:00:35 2022 +0100

EFI: relocate the ESRT when booting via multiboot2

This was missed in the initial patchset.

Move efi_relocate_esrt() up to avoid adding a forward declaration.

Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
xen/arch/x86/efi/efi-boot.h | 2 +
xen/common/efi/boot.c | 136 ++++++++++++++++++++++----------------------
2 files changed, 70 insertions(+), 68 deletions(-)

diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h
index 27f928ed3c..c94e53d139 100644
--- a/xen/arch/x86/efi/efi-boot.h
+++ b/xen/arch/x86/efi/efi-boot.h
@@ -823,6 +823,8 @@ void __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable
if ( gop )
efi_set_gop_mode(gop, gop_mode);

+ efi_relocate_esrt(SystemTable);
+
efi_exit_boot(ImageHandle, SystemTable);
}

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index b3de1011ee..d3c6b055ae 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -625,6 +625,74 @@ static size_t __init get_esrt_size(const EFI_MEMORY_DESCRIPTOR *desc)
return esrt_ptr->FwResourceCount * sizeof(esrt_ptr->Entries[0]);
}

+static EFI_GUID __initdata esrt_guid = EFI_SYSTEM_RESOURCE_TABLE_GUID;
+
+static void __init efi_relocate_esrt(EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS status;
+ UINTN info_size = 0, map_key, mdesc_size;
+ void *memory_map = NULL;
+ UINT32 ver;
+ unsigned int i;
+
+ for ( ; ; )
+ {
+ status = efi_bs->GetMemoryMap(&info_size, memory_map, &map_key,
+ &mdesc_size, &ver);
+ if ( status == EFI_SUCCESS && memory_map != NULL )
+ break;
+ if ( status == EFI_BUFFER_TOO_SMALL || memory_map == NULL )
+ {
+ info_size += 8 * mdesc_size;
+ if ( memory_map != NULL )
+ efi_bs->FreePool(memory_map);
+ memory_map = NULL;
+ status = efi_bs->AllocatePool(EfiLoaderData, info_size, &memory_map);
+ if ( status == EFI_SUCCESS )
+ continue;
+ PrintErr(L"Cannot allocate memory to relocate ESRT\r\n");
+ }
+ else
+ PrintErr(L"Cannot obtain memory map to relocate ESRT\r\n");
+ return;
+ }
+
+ /* Try to obtain the ESRT. Errors are not fatal. */
+ for ( i = 0; i < info_size; i += mdesc_size )
+ {
+ /*
+ * ESRT needs to be moved to memory of type EfiACPIReclaimMemory
+ * so that the memory it is in will not be used for other purposes.
+ */
+ void *new_esrt = NULL;
+ const EFI_MEMORY_DESCRIPTOR *desc = memory_map + i;
+ size_t esrt_size = get_esrt_size(desc);
+
+ if ( !esrt_size )
+ continue;
+ if ( desc->Type == EfiRuntimeServicesData ||
+ desc->Type == EfiACPIReclaimMemory )
+ break; /* ESRT already safe from reuse */
+ status = efi_bs->AllocatePool(EfiACPIReclaimMemory, esrt_size,
+ &new_esrt);
+ if ( status == EFI_SUCCESS && new_esrt )
+ {
+ memcpy(new_esrt, (void *)esrt, esrt_size);
+ status = efi_bs->InstallConfigurationTable(&esrt_guid, new_esrt);
+ if ( status != EFI_SUCCESS )
+ {
+ PrintErr(L"Cannot install new ESRT\r\n");
+ efi_bs->FreePool(new_esrt);
+ }
+ }
+ else
+ PrintErr(L"Cannot allocate memory for ESRT\r\n");
+ break;
+ }
+
+ efi_bs->FreePool(memory_map);
+}
+
/*
* Include architecture specific implementation here, which references the
* static globals defined above.
@@ -903,8 +971,6 @@ static UINTN __init efi_find_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
return gop_mode;
}

-static EFI_GUID __initdata esrt_guid = EFI_SYSTEM_RESOURCE_TABLE_GUID;
-
static void __init efi_tables(void)
{
unsigned int i;
@@ -1113,72 +1179,6 @@ static void __init efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop
#define INVALID_VIRTUAL_ADDRESS (0xBAAADUL << \
(EFI_PAGE_SHIFT + BITS_PER_LONG - 32))

-static void __init efi_relocate_esrt(EFI_SYSTEM_TABLE *SystemTable)
-{
- EFI_STATUS status;
- UINTN info_size = 0, map_key, mdesc_size;
- void *memory_map = NULL;
- UINT32 ver;
- unsigned int i;
-
- for ( ; ; )
- {
- status = efi_bs->GetMemoryMap(&info_size, memory_map, &map_key,
- &mdesc_size, &ver);
- if ( status == EFI_SUCCESS && memory_map != NULL )
- break;
- if ( status == EFI_BUFFER_TOO_SMALL || memory_map == NULL )
- {
- info_size += 8 * mdesc_size;
- if ( memory_map != NULL )
- efi_bs->FreePool(memory_map);
- memory_map = NULL;
- status = efi_bs->AllocatePool(EfiLoaderData, info_size, &memory_map);
- if ( status == EFI_SUCCESS )
- continue;
- PrintErr(L"Cannot allocate memory to relocate ESRT\r\n");
- }
- else
- PrintErr(L"Cannot obtain memory map to relocate ESRT\r\n");
- return;
- }
-
- /* Try to obtain the ESRT. Errors are not fatal. */
- for ( i = 0; i < info_size; i += mdesc_size )
- {
- /*
- * ESRT needs to be moved to memory of type EfiACPIReclaimMemory
- * so that the memory it is in will not be used for other purposes.
- */
- void *new_esrt = NULL;
- const EFI_MEMORY_DESCRIPTOR *desc = memory_map + i;
- size_t esrt_size = get_esrt_size(desc);
-
- if ( !esrt_size )
- continue;
- if ( desc->Type == EfiRuntimeServicesData ||
- desc->Type == EfiACPIReclaimMemory )
- break; /* ESRT already safe from reuse */
- status = efi_bs->AllocatePool(EfiACPIReclaimMemory, esrt_size,
- &new_esrt);
- if ( status == EFI_SUCCESS && new_esrt )
- {
- memcpy(new_esrt, (void *)esrt, esrt_size);
- status = efi_bs->InstallConfigurationTable(&esrt_guid, new_esrt);
- if ( status != EFI_SUCCESS )
- {
- PrintErr(L"Cannot install new ESRT\r\n");
- efi_bs->FreePool(new_esrt);
- }
- }
- else
- PrintErr(L"Cannot allocate memory for ESRT\r\n");
- break;
- }
-
- efi_bs->FreePool(memory_map);
-}
-
static void __init efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS status;
--
generated by git-patchbot for /home/xen/git/xen.git#master