Commit ed9cc156 authored by Jeffrey Hugo's avatar Jeffrey Hugo Committed by Matt Fleming

efi/libstub: Use efi_exit_boot_services() in FDT

The FDT code directly calls ExitBootServices.  This is inadvisable as the
UEFI spec details a complex set of errors, race conditions, and API
interactions that the caller of ExitBootServices must get correct.  The
FDT code does not handle EFI_INVALID_PARAMETER as required by the spec,
which causes intermittent boot failures on the Qualcomm Technologies
QDF2432.  Call the efi_exit_boot_services() helper intead, which handles
the EFI_INVALID_PARAMETER scenario properly.
Signed-off-by: default avatarJeffrey 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: default avatarMatt Fleming <matt@codeblueprint.co.uk>
parent fc07716b
...@@ -152,6 +152,27 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, ...@@ -152,6 +152,27 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
#define EFI_FDT_ALIGN EFI_PAGE_SIZE #define EFI_FDT_ALIGN EFI_PAGE_SIZE
#endif #endif
struct exit_boot_struct {
efi_memory_desc_t *runtime_map;
int *runtime_entry_count;
};
static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
struct efi_boot_memmap *map,
void *priv)
{
struct exit_boot_struct *p = priv;
/*
* Update the memory map with virtual addresses. The function will also
* populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME
* entries so that we can pass it straight to SetVirtualAddressMap()
*/
efi_get_virtmap(*map->map, *map->map_size, *map->desc_size,
p->runtime_map, p->runtime_entry_count);
return EFI_SUCCESS;
}
/* /*
* Allocate memory for a new FDT, then add EFI, commandline, and * Allocate memory for a new FDT, then add EFI, commandline, and
* initrd related fields to the FDT. This routine increases the * initrd related fields to the FDT. This routine increases the
...@@ -183,6 +204,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, ...@@ -183,6 +204,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
efi_status_t status; efi_status_t status;
int runtime_entry_count = 0; int runtime_entry_count = 0;
struct efi_boot_memmap map; struct efi_boot_memmap map;
struct exit_boot_struct priv;
map.map = &runtime_map; map.map = &runtime_map;
map.map_size = &map_size; map.map_size = &map_size;
...@@ -257,16 +279,11 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, ...@@ -257,16 +279,11 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
} }
} }
/* sys_table->boottime->free_pool(memory_map);
* Update the memory map with virtual addresses. The function will also priv.runtime_map = runtime_map;
* populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME priv.runtime_entry_count = &runtime_entry_count;
* entries so that we can pass it straight into SetVirtualAddressMap() status = efi_exit_boot_services(sys_table, handle, &map, &priv,
*/ exit_boot_func);
efi_get_virtmap(memory_map, map_size, desc_size, runtime_map,
&runtime_entry_count);
/* Now we are ready to exit_boot_services.*/
status = sys_table->boottime->exit_boot_services(handle, mmap_key);
if (status == EFI_SUCCESS) { if (status == EFI_SUCCESS) {
efi_set_virtual_address_map_t *svam; efi_set_virtual_address_map_t *svam;
......
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