Skip to content

Commit ed9cc15

Browse files
Jeffrey Hugomfleming
Jeffrey Hugo
authored andcommitted
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: Jeffrey Hugo <[email protected]> Cc: Ard Biesheuvel <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Leif Lindholm <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: <[email protected]> Signed-off-by: Matt Fleming <[email protected]>
1 parent fc07716 commit ed9cc15

File tree

1 file changed

+27
-10
lines changed
  • drivers/firmware/efi/libstub

1 file changed

+27
-10
lines changed

drivers/firmware/efi/libstub/fdt.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,27 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
152152
#define EFI_FDT_ALIGN EFI_PAGE_SIZE
153153
#endif
154154

155+
struct exit_boot_struct {
156+
efi_memory_desc_t *runtime_map;
157+
int *runtime_entry_count;
158+
};
159+
160+
static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg,
161+
struct efi_boot_memmap *map,
162+
void *priv)
163+
{
164+
struct exit_boot_struct *p = priv;
165+
/*
166+
* Update the memory map with virtual addresses. The function will also
167+
* populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME
168+
* entries so that we can pass it straight to SetVirtualAddressMap()
169+
*/
170+
efi_get_virtmap(*map->map, *map->map_size, *map->desc_size,
171+
p->runtime_map, p->runtime_entry_count);
172+
173+
return EFI_SUCCESS;
174+
}
175+
155176
/*
156177
* Allocate memory for a new FDT, then add EFI, commandline, and
157178
* 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,
183204
efi_status_t status;
184205
int runtime_entry_count = 0;
185206
struct efi_boot_memmap map;
207+
struct exit_boot_struct priv;
186208

187209
map.map = &runtime_map;
188210
map.map_size = &map_size;
@@ -257,16 +279,11 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
257279
}
258280
}
259281

260-
/*
261-
* Update the memory map with virtual addresses. The function will also
262-
* populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME
263-
* entries so that we can pass it straight into SetVirtualAddressMap()
264-
*/
265-
efi_get_virtmap(memory_map, map_size, desc_size, runtime_map,
266-
&runtime_entry_count);
267-
268-
/* Now we are ready to exit_boot_services.*/
269-
status = sys_table->boottime->exit_boot_services(handle, mmap_key);
282+
sys_table->boottime->free_pool(memory_map);
283+
priv.runtime_map = runtime_map;
284+
priv.runtime_entry_count = &runtime_entry_count;
285+
status = efi_exit_boot_services(sys_table, handle, &map, &priv,
286+
exit_boot_func);
270287

271288
if (status == EFI_SUCCESS) {
272289
efi_set_virtual_address_map_t *svam;

0 commit comments

Comments
 (0)