]> git.baikalelectronics.ru Git - kernel.git/commitdiff
efi: libstub: install boot-time memory map as config table
authorArd Biesheuvel <ardb@kernel.org>
Thu, 15 Sep 2022 21:20:06 +0000 (23:20 +0200)
committerArd Biesheuvel <ardb@kernel.org>
Tue, 27 Sep 2022 11:22:49 +0000 (13:22 +0200)
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>
drivers/firmware/efi/libstub/arm64-stub.c
drivers/firmware/efi/libstub/efi-stub-helper.c
drivers/firmware/efi/libstub/efistub.h
drivers/firmware/efi/libstub/mem.c
drivers/firmware/efi/libstub/randomalloc.c
drivers/firmware/efi/libstub/relocate.c
include/linux/efi.h

index 83b5ae3721ea0534b376799d574c3df36b269744..cd3bea25c7628b194b8fd73e8d903ae94dd33ecc 100644 (file)
@@ -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;
 
index a671eaad7503d54d0b0894d0cfc75ff3c66323dc..e3ee8383e02cdf6b8b5480275829cc22c36f9e81 100644 (file)
@@ -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;
 
index f06d753a1ec96f9f6b89e4a8a752208343282c8c..fc90e453bbbb5cd581714208b608b79f0cda8109 100644 (file)
@@ -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);
index c92b7dbc6dfe6d820817cc4f326627d927606858..45841ef55a9f6ba284ec7f4bd34fc24a6b91451e 100644 (file)
@@ -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;
index 5d6000c717ccbf0f8092668fd49d7aed936d2ad5..9fb5869896be7340c9bb7f4141c4cf93c9a4bbca 100644 (file)
@@ -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;
 
index cd80db33ab1e759a5da61710581172b3d61bfe60..bf6fbd5d22a1a53af196be2a15f5593468f78da4 100644 (file)
@@ -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;
 
index 778ddb22f7daf9a51dc54121242f1ad5347edc4a..252b9b328577e77de5695422e1cc3cff5beee5cd 100644 (file)
@@ -410,6 +410,7 @@ void efi_native_runtime_setup(void);
 #define LINUX_EFI_INITRD_MEDIA_GUID            EFI_GUID(0x5568e427, 0x68fc, 0x4f3d,  0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
 #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_BOOT_MEMMAP_GUID             EFI_GUID(0x800f683f, 0xd08b, 0x423a,  0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
 
 #define RISCV_EFI_BOOT_PROTOCOL_GUID           EFI_GUID(0xccd15fec, 0x6f73, 0x4eec,  0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf)