aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/efi/libstub/fdt.c
diff options
context:
space:
mode:
authorJeffrey Hugo <jhugo@codeaurora.org>2016-08-29 16:38:51 -0400
committerMatt Fleming <matt@codeblueprint.co.uk>2016-09-05 07:18:17 -0400
commitdadb57abc37499f565b23933dbf49b435c3ba8af (patch)
tree80721c262bfd0a51f3448b09d6a4b392701f2202 /drivers/firmware/efi/libstub/fdt.c
parent4af9ed578a50cd331a725322cfd9d555251ce788 (diff)
efi/libstub: Allocate headspace in efi_get_memory_map()
efi_get_memory_map() allocates a buffer to store the memory map that it retrieves. This buffer may need to be reused by the client after ExitBootServices() is called, at which point allocations are not longer permitted. To support this usecase, provide the allocated buffer size back to the client, and allocate some additional headroom to account for any reasonable growth in the map that is likely to happen between the call to efi_get_memory_map() and the client reusing the buffer. Signed-off-by: Jeffrey Hugo <jhugo@codeaurora.org> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Leif Lindholm <leif.lindholm@linaro.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: <stable@vger.kernel.org> Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Diffstat (limited to 'drivers/firmware/efi/libstub/fdt.c')
-rw-r--r--drivers/firmware/efi/libstub/fdt.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index e58abfa953cc..bec0fa8d8746 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -175,13 +175,21 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
175 unsigned long fdt_addr, 175 unsigned long fdt_addr,
176 unsigned long fdt_size) 176 unsigned long fdt_size)
177{ 177{
178 unsigned long map_size, desc_size; 178 unsigned long map_size, desc_size, buff_size;
179 u32 desc_ver; 179 u32 desc_ver;
180 unsigned long mmap_key; 180 unsigned long mmap_key;
181 efi_memory_desc_t *memory_map, *runtime_map; 181 efi_memory_desc_t *memory_map, *runtime_map;
182 unsigned long new_fdt_size; 182 unsigned long new_fdt_size;
183 efi_status_t status; 183 efi_status_t status;
184 int runtime_entry_count = 0; 184 int runtime_entry_count = 0;
185 struct efi_boot_memmap map;
186
187 map.map = &runtime_map;
188 map.map_size = &map_size;
189 map.desc_size = &desc_size;
190 map.desc_ver = &desc_ver;
191 map.key_ptr = &mmap_key;
192 map.buff_size = &buff_size;
185 193
186 /* 194 /*
187 * Get a copy of the current memory map that we will use to prepare 195 * Get a copy of the current memory map that we will use to prepare
@@ -189,8 +197,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
189 * subsequent allocations adding entries, since they could not affect 197 * subsequent allocations adding entries, since they could not affect
190 * the number of EFI_MEMORY_RUNTIME regions. 198 * the number of EFI_MEMORY_RUNTIME regions.
191 */ 199 */
192 status = efi_get_memory_map(sys_table, &runtime_map, &map_size, 200 status = efi_get_memory_map(sys_table, &map);
193 &desc_size, &desc_ver, &mmap_key);
194 if (status != EFI_SUCCESS) { 201 if (status != EFI_SUCCESS) {
195 pr_efi_err(sys_table, "Unable to retrieve UEFI memory map.\n"); 202 pr_efi_err(sys_table, "Unable to retrieve UEFI memory map.\n");
196 return status; 203 return status;
@@ -199,6 +206,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
199 pr_efi(sys_table, 206 pr_efi(sys_table,
200 "Exiting boot services and installing virtual address map...\n"); 207 "Exiting boot services and installing virtual address map...\n");
201 208
209 map.map = &memory_map;
202 /* 210 /*
203 * Estimate size of new FDT, and allocate memory for it. We 211 * Estimate size of new FDT, and allocate memory for it. We
204 * will allocate a bigger buffer if this ends up being too 212 * will allocate a bigger buffer if this ends up being too
@@ -218,8 +226,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
218 * we can get the memory map key needed for 226 * we can get the memory map key needed for
219 * exit_boot_services(). 227 * exit_boot_services().
220 */ 228 */
221 status = efi_get_memory_map(sys_table, &memory_map, &map_size, 229 status = efi_get_memory_map(sys_table, &map);
222 &desc_size, &desc_ver, &mmap_key);
223 if (status != EFI_SUCCESS) 230 if (status != EFI_SUCCESS)
224 goto fail_free_new_fdt; 231 goto fail_free_new_fdt;
225 232