Commit a643375f authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Matt Fleming

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: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: default avatarRoy Franz <roy.franz@linaro.org>
Signed-off-by: default avatarMatt Fleming <matt.fleming@intel.com>
parent 744937b0
......@@ -175,7 +175,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
unsigned long initrd_addr;
u64 initrd_size = 0;
unsigned long fdt_addr = 0; /* Original DTB */
u64 fdt_size = 0; /* We don't get size from configuration table */
unsigned long fdt_size = 0;
char *cmdline_ptr = NULL;
int cmdline_size = 0;
unsigned long new_fdt_addr;
......@@ -239,8 +239,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
} else {
status = handle_cmdline_files(sys_table, image, cmdline_ptr,
"dtb=",
~0UL, (unsigned long *)&fdt_addr,
(unsigned long *)&fdt_size);
~0UL, &fdt_addr, &fdt_size);
if (status != EFI_SUCCESS) {
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,
pr_efi(sys_table, "Using DTB from command line\n");
} else {
/* Look for a device tree configuration table entry. */
fdt_addr = (uintptr_t)get_fdt(sys_table);
fdt_addr = (uintptr_t)get_fdt(sys_table, &fdt_size);
if (fdt_addr)
pr_efi(sys_table, "Using DTB from configuration table\n");
}
......
......@@ -41,7 +41,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
unsigned long fdt_addr,
unsigned long fdt_size);
void *get_fdt(efi_system_table_t *sys_table);
void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size);
void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
unsigned long desc_size, efi_memory_desc_t *runtime_map,
......
......@@ -323,7 +323,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
return EFI_LOAD_ERROR;
}
void *get_fdt(efi_system_table_t *sys_table)
void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size)
{
efi_guid_t fdt_guid = DEVICE_TREE_GUID;
efi_config_table_t *tables;
......@@ -336,6 +336,11 @@ void *get_fdt(efi_system_table_t *sys_table)
for (i = 0; i < sys_table->nr_tables; i++)
if (efi_guidcmp(tables[i].guid, fdt_guid) == 0) {
fdt = (void *) tables[i].table;
if (fdt_check_header(fdt) != 0) {
pr_efi_err(sys_table, "Invalid header detected on UEFI supplied FDT, ignoring ...\n");
return NULL;
}
*fdt_size = fdt_totalsize(fdt);
break;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment