summaryrefslogtreecommitdiff
path: root/drivers/firmware/efi
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2022-09-16 00:20:06 +0300
committerArd Biesheuvel <ardb@kernel.org>2022-09-27 14:22:49 +0300
commit171539f5a90e3fdf7d17f5396fac79d7e44ad68e (patch)
tree388301a71f5475a8c2bc922aaeabf46280efbeb6 /drivers/firmware/efi
parent4fc8e738ff3e6a208855bb69783280870c7cf251 (diff)
downloadlinux-171539f5a90e3fdf7d17f5396fac79d7e44ad68e.tar.xz
efi: libstub: install boot-time memory map as config table
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>
Diffstat (limited to 'drivers/firmware/efi')
-rw-r--r--drivers/firmware/efi/libstub/arm64-stub.c2
-rw-r--r--drivers/firmware/efi/libstub/efi-stub-helper.c2
-rw-r--r--drivers/firmware/efi/libstub/efistub.h3
-rw-r--r--drivers/firmware/efi/libstub/mem.c27
-rw-r--r--drivers/firmware/efi/libstub/randomalloc.c2
-rw-r--r--drivers/firmware/efi/libstub/relocate.c2
6 files changed, 30 insertions, 8 deletions
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index 83b5ae3721ea..cd3bea25c762 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -47,7 +47,7 @@ static bool check_image_region(u64 base, u64 size)
bool ret = false;
int map_offset;
- status = efi_get_memory_map(&map);
+ status = efi_get_memory_map(&map, false);
if (status != EFI_SUCCESS)
return false;
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index a671eaad7503..e3ee8383e02c 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -437,7 +437,7 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv,
struct efi_boot_memmap *map;
efi_status_t status;
- status = efi_get_memory_map(&map);
+ status = efi_get_memory_map(&map, true);
if (status != EFI_SUCCESS)
return status;
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index f06d753a1ec9..fc90e453bbbb 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -876,7 +876,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);
-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,
unsigned long max);
diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c
index c92b7dbc6dfe..45841ef55a9f 100644
--- a/drivers/firmware/efi/libstub/mem.c
+++ b/drivers/firmware/efi/libstub/mem.c
@@ -9,14 +9,20 @@
* efi_get_memory_map() - get memory map
* @map: pointer to memory map pointer to which to assign the
* 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
* up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries.
*
* 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;
efi_status_t status;
unsigned long size;
@@ -28,20 +34,35 @@ efi_status_t efi_get_memory_map(struct efi_boot_memmap **map)
return EFI_LOAD_ERROR;
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);
if (status != EFI_SUCCESS)
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;
status = efi_bs_call(get_memory_map, &m->map_size, m->map, &m->map_key,
&m->desc_size, &m->desc_ver);
if (status != EFI_SUCCESS)
- goto free_map;
+ goto uninstall_table;
*map = m;
return EFI_SUCCESS;
+uninstall_table:
+ if (install_cfg_tbl)
+ efi_bs_call(install_configuration_table, &tbl_guid, NULL);
free_map:
efi_bs_call(free_pool, m);
return status;
diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c
index 5d6000c717cc..9fb5869896be 100644
--- a/drivers/firmware/efi/libstub/randomalloc.c
+++ b/drivers/firmware/efi/libstub/randomalloc.c
@@ -61,7 +61,7 @@ efi_status_t efi_random_alloc(unsigned long size,
efi_status_t status;
int map_offset;
- status = efi_get_memory_map(&map);
+ status = efi_get_memory_map(&map, false);
if (status != EFI_SUCCESS)
return status;
diff --git a/drivers/firmware/efi/libstub/relocate.c b/drivers/firmware/efi/libstub/relocate.c
index cd80db33ab1e..bf6fbd5d22a1 100644
--- a/drivers/firmware/efi/libstub/relocate.c
+++ b/drivers/firmware/efi/libstub/relocate.c
@@ -28,7 +28,7 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
unsigned long nr_pages;
int i;
- status = efi_get_memory_map(&map);
+ status = efi_get_memory_map(&map, false);
if (status != EFI_SUCCESS)
goto fail;