aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/efi
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2015-03-04 07:02:29 -0500
committerMatt Fleming <matt.fleming@intel.com>2015-04-01 07:46:23 -0400
commita643375f4b175569bc3c03c7a3e758f845c1ccd9 (patch)
tree89b4845b7d2ff481efcf23dfbf0f5e6b328e1701 /drivers/firmware/efi
parent744937b0b12a669f298949c4a810794c59fead98 (diff)
efi/libstub: Retrieve FDT size when loaded from UEFI config table
When allocating memory for the copy of the FDT that the stub modifies and passes to the kernel, it uses the current size as an estimate of how much memory to allocate, and increases it page by page if it turns out to be too small. However, when loading the FDT from a UEFI configuration table, the estimated size is left at its default value of zero, and the allocation loop runs starting from zero all the way up to the allocation size that finally fits the updated FDT. Instead, retrieve the size of the FDT from the FDT header when loading it from the UEFI config table. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Roy Franz <roy.franz@linaro.org> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'drivers/firmware/efi')
-rw-r--r--drivers/firmware/efi/libstub/arm-stub.c7
-rw-r--r--drivers/firmware/efi/libstub/efistub.h2
-rw-r--r--drivers/firmware/efi/libstub/fdt.c7
3 files changed, 10 insertions, 6 deletions
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index dcae482a9a17..e29560e6b40b 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -175,7 +175,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
175 unsigned long initrd_addr; 175 unsigned long initrd_addr;
176 u64 initrd_size = 0; 176 u64 initrd_size = 0;
177 unsigned long fdt_addr = 0; /* Original DTB */ 177 unsigned long fdt_addr = 0; /* Original DTB */
178 u64 fdt_size = 0; /* We don't get size from configuration table */ 178 unsigned long fdt_size = 0;
179 char *cmdline_ptr = NULL; 179 char *cmdline_ptr = NULL;
180 int cmdline_size = 0; 180 int cmdline_size = 0;
181 unsigned long new_fdt_addr; 181 unsigned long new_fdt_addr;
@@ -239,8 +239,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
239 } else { 239 } else {
240 status = handle_cmdline_files(sys_table, image, cmdline_ptr, 240 status = handle_cmdline_files(sys_table, image, cmdline_ptr,
241 "dtb=", 241 "dtb=",
242 ~0UL, (unsigned long *)&fdt_addr, 242 ~0UL, &fdt_addr, &fdt_size);
243 (unsigned long *)&fdt_size);
244 243
245 if (status != EFI_SUCCESS) { 244 if (status != EFI_SUCCESS) {
246 pr_efi_err(sys_table, "Failed to load device tree!\n"); 245 pr_efi_err(sys_table, "Failed to load device tree!\n");
@@ -252,7 +251,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
252 pr_efi(sys_table, "Using DTB from command line\n"); 251 pr_efi(sys_table, "Using DTB from command line\n");
253 } else { 252 } else {
254 /* Look for a device tree configuration table entry. */ 253 /* Look for a device tree configuration table entry. */
255 fdt_addr = (uintptr_t)get_fdt(sys_table); 254 fdt_addr = (uintptr_t)get_fdt(sys_table, &fdt_size);
256 if (fdt_addr) 255 if (fdt_addr)
257 pr_efi(sys_table, "Using DTB from configuration table\n"); 256 pr_efi(sys_table, "Using DTB from configuration table\n");
258 } 257 }
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 47437b16b186..e334a01cf92f 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -41,7 +41,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
41 unsigned long fdt_addr, 41 unsigned long fdt_addr,
42 unsigned long fdt_size); 42 unsigned long fdt_size);
43 43
44void *get_fdt(efi_system_table_t *sys_table); 44void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size);
45 45
46void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, 46void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
47 unsigned long desc_size, efi_memory_desc_t *runtime_map, 47 unsigned long desc_size, efi_memory_desc_t *runtime_map,
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 91da56c4fd54..ef5d764e2a27 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -323,7 +323,7 @@ fail:
323 return EFI_LOAD_ERROR; 323 return EFI_LOAD_ERROR;
324} 324}
325 325
326void *get_fdt(efi_system_table_t *sys_table) 326void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size)
327{ 327{
328 efi_guid_t fdt_guid = DEVICE_TREE_GUID; 328 efi_guid_t fdt_guid = DEVICE_TREE_GUID;
329 efi_config_table_t *tables; 329 efi_config_table_t *tables;
@@ -336,6 +336,11 @@ void *get_fdt(efi_system_table_t *sys_table)
336 for (i = 0; i < sys_table->nr_tables; i++) 336 for (i = 0; i < sys_table->nr_tables; i++)
337 if (efi_guidcmp(tables[i].guid, fdt_guid) == 0) { 337 if (efi_guidcmp(tables[i].guid, fdt_guid) == 0) {
338 fdt = (void *) tables[i].table; 338 fdt = (void *) tables[i].table;
339 if (fdt_check_header(fdt) != 0) {
340 pr_efi_err(sys_table, "Invalid header detected on UEFI supplied FDT, ignoring ...\n");
341 return NULL;
342 }
343 *fdt_size = fdt_totalsize(fdt);
339 break; 344 break;
340 } 345 }
341 346