efi: libstub: install boot-time memory map as config table

ANBZ: #9469

commit 171539f5a9 upstream

Expose the EFI boot time memory map to the kernel via a configuration
table. This is arch agnostic and enables future changes that remove the
dependency on DT on architectures that don't otherwise rely on it.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Zelin Deng <zelin.deng@linux.alibaba.com>
Reviewed-by: Xuchun Shang <xuchun.shang@linux.alibaba.com>
Link: https://gitee.com/anolis/cloud-kernel/pulls/3457
This commit is contained in:
Ard Biesheuvel 2022-09-15 23:20:06 +02:00 committed by 小龙
parent c95cce65bc
commit 4ac2c439f2
7 changed files with 31 additions and 8 deletions

View File

@ -47,7 +47,7 @@ static bool check_image_region(u64 base, u64 size)
bool ret = false; bool ret = false;
int map_offset; int map_offset;
status = efi_get_memory_map(&map); status = efi_get_memory_map(&map, false);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return false; return false;

View File

@ -437,7 +437,7 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv,
struct efi_boot_memmap *map; struct efi_boot_memmap *map;
efi_status_t status; efi_status_t status;
status = efi_get_memory_map(&map); status = efi_get_memory_map(&map, true);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return status; return status;

View File

@ -795,7 +795,8 @@ void efi_apply_loadoptions_quirk(const void **load_options, int *load_options_si
char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len); char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len);
efi_status_t efi_get_memory_map(struct efi_boot_memmap **map); efi_status_t efi_get_memory_map(struct efi_boot_memmap **map,
bool install_cfg_tbl);
efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr, efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr,
unsigned long max); unsigned long max);

View File

@ -9,14 +9,20 @@
* efi_get_memory_map() - get memory map * efi_get_memory_map() - get memory map
* @map: pointer to memory map pointer to which to assign the * @map: pointer to memory map pointer to which to assign the
* newly allocated memory map * newly allocated memory map
* @install_cfg_tbl: whether or not to install the boot memory map as a
* configuration table
* *
* Retrieve the UEFI memory map. The allocated memory leaves room for * Retrieve the UEFI memory map. The allocated memory leaves room for
* up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries. * up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries.
* *
* Return: status code * Return: status code
*/ */
efi_status_t efi_get_memory_map(struct efi_boot_memmap **map) efi_status_t efi_get_memory_map(struct efi_boot_memmap **map,
bool install_cfg_tbl)
{ {
int memtype = install_cfg_tbl ? EFI_ACPI_RECLAIM_MEMORY
: EFI_LOADER_DATA;
efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID;
struct efi_boot_memmap *m, tmp; struct efi_boot_memmap *m, tmp;
efi_status_t status; efi_status_t status;
unsigned long size; unsigned long size;
@ -28,20 +34,35 @@ efi_status_t efi_get_memory_map(struct efi_boot_memmap **map)
return EFI_LOAD_ERROR; return EFI_LOAD_ERROR;
size = tmp.map_size + tmp.desc_size * EFI_MMAP_NR_SLACK_SLOTS; size = tmp.map_size + tmp.desc_size * EFI_MMAP_NR_SLACK_SLOTS;
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(*m) + size, status = efi_bs_call(allocate_pool, memtype, sizeof(*m) + size,
(void **)&m); (void **)&m);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return status; return status;
if (install_cfg_tbl) {
/*
* Installing a configuration table might allocate memory, and
* this may modify the memory map. This means we should install
* the configuration table first, and re-install or delete it
* as needed.
*/
status = efi_bs_call(install_configuration_table, &tbl_guid, m);
if (status != EFI_SUCCESS)
goto free_map;
}
m->buff_size = m->map_size = size; m->buff_size = m->map_size = size;
status = efi_bs_call(get_memory_map, &m->map_size, m->map, &m->map_key, status = efi_bs_call(get_memory_map, &m->map_size, m->map, &m->map_key,
&m->desc_size, &m->desc_ver); &m->desc_size, &m->desc_ver);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
goto free_map; goto uninstall_table;
*map = m; *map = m;
return EFI_SUCCESS; return EFI_SUCCESS;
uninstall_table:
if (install_cfg_tbl)
efi_bs_call(install_configuration_table, &tbl_guid, NULL);
free_map: free_map:
efi_bs_call(free_pool, m); efi_bs_call(free_pool, m);
return status; return status;

View File

@ -61,7 +61,7 @@ efi_status_t efi_random_alloc(unsigned long size,
efi_status_t status; efi_status_t status;
int map_offset; int map_offset;
status = efi_get_memory_map(&map); status = efi_get_memory_map(&map, false);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return status; return status;

View File

@ -28,7 +28,7 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
unsigned long nr_pages; unsigned long nr_pages;
int i; int i;
status = efi_get_memory_map(&map); status = efi_get_memory_map(&map, false);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
goto fail; goto fail;

View File

@ -368,6 +368,7 @@ void efi_native_runtime_setup(void);
#define LINUX_EFI_ZBOOT_MEDIA_GUID EFI_GUID(0xe565a30d, 0x47da, 0x4dbd, 0xb3, 0x54, 0x9b, 0xb5, 0xc8, 0x4f, 0x8b, 0xe2) #define LINUX_EFI_ZBOOT_MEDIA_GUID EFI_GUID(0xe565a30d, 0x47da, 0x4dbd, 0xb3, 0x54, 0x9b, 0xb5, 0xc8, 0x4f, 0x8b, 0xe2)
#define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89) #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89)
#define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47) #define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47)
#define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
/* OEM GUIDs */ /* OEM GUIDs */
#define DELLEMC_EFI_RCI2_TABLE_GUID EFI_GUID(0x2d9f28a2, 0xa886, 0x456a, 0x97, 0xa8, 0xf1, 0x1e, 0xf2, 0x4f, 0xf4, 0x55) #define DELLEMC_EFI_RCI2_TABLE_GUID EFI_GUID(0x2d9f28a2, 0xa886, 0x456a, 0x97, 0xa8, 0xf1, 0x1e, 0xf2, 0x4f, 0xf4, 0x55)