summaryrefslogtreecommitdiff
path: root/drivers/firmware/efi/libstub/efi-stub.c
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2022-09-15 20:45:35 +0300
committerArd Biesheuvel <ardb@kernel.org>2022-09-26 23:29:24 +0300
commitf80d26043af91ceb5036c478101c015edb9e7630 (patch)
tree00514d5a2f28a3d7ae7d4f82b978ae4ae961c559 /drivers/firmware/efi/libstub/efi-stub.c
parentd80ca810f096ff66f451e7a3ed2f0cd9ef1ff519 (diff)
downloadlinux-f80d26043af91ceb5036c478101c015edb9e7630.tar.xz
efi: libstub: avoid efi_get_memory_map() for allocating the virt map
The virt map is a set of efi_memory_desc_t descriptors that are passed to SetVirtualAddressMap() to inform the firmware about the desired virtual mapping of the regions marked as EFI_MEMORY_RUNTIME. The only reason we currently call the efi_get_memory_map() helper is that it gives us an allocation that is guaranteed to be of sufficient size. However, efi_get_memory_map() has grown some additional complexity over the years, and today, we're actually better off calling the EFI boot service directly with a zero size, which tells us how much memory should be enough for the virt map. While at it, avoid creating the VA map allocation if we will not be using it anyway, i.e., if efi_novamap is true. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Diffstat (limited to 'drivers/firmware/efi/libstub/efi-stub.c')
-rw-r--r--drivers/firmware/efi/libstub/efi-stub.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index 4bf751484e8b..90d44834e33e 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -322,6 +322,35 @@ fail:
}
/*
+ * efi_allocate_virtmap() - create a pool allocation for the virtmap
+ *
+ * Create an allocation that is of sufficient size to hold all the memory
+ * descriptors that will be passed to SetVirtualAddressMap() to inform the
+ * firmware about the virtual mapping that will be used under the OS to call
+ * into the firmware.
+ */
+efi_status_t efi_alloc_virtmap(efi_memory_desc_t **virtmap,
+ unsigned long *desc_size, u32 *desc_ver)
+{
+ unsigned long size, mmap_key;
+ efi_status_t status;
+
+ /*
+ * Use the size of the current memory map as an upper bound for the
+ * size of the buffer we need to pass to SetVirtualAddressMap() to
+ * cover all EFI_MEMORY_RUNTIME regions.
+ */
+ size = 0;
+ status = efi_bs_call(get_memory_map, &size, NULL, &mmap_key, desc_size,
+ desc_ver);
+ if (status != EFI_BUFFER_TOO_SMALL)
+ return EFI_LOAD_ERROR;
+
+ return efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
+ (void **)virtmap);
+}
+
+/*
* efi_get_virtmap() - create a virtual mapping for the EFI memory map
*
* This function populates the virt_addr fields of all memory region descriptors
@@ -336,6 +365,8 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
efi_memory_desc_t *in, *out = runtime_map;
int l;
+ *count = 0;
+
for (l = 0; l < map_size; l += desc_size) {
u64 paddr, size;