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>
This commit is contained in:
Demi Marie Obenour authored and Jan Beulich committed 2022-12-14 12:00:35 +01:00
1 parent 630dc3798e
commit 8d7acf3f7d
2 files changed
+70 -68

No files matched your search

+2
View File
@@ -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);
}
+68 -68
View File
@@ -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;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.