diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 3d972061c1b0..16586fb1b4a1 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -416,6 +416,11 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len) return (char *)cmdline_addr; } +void efi_boot_memmap_report(struct efi_boot_memmap *map) +{ + efi_debug("efi_boot_memmap = {map=0x%p map_size=0x%lx desc_size=0x%lx desc_ver=0x%x key_ptr=0x%p *key_ptr=0x%lx buff_size=0x%lx }\n" , map->map, *map->map_size, *map->desc_size, *map->desc_ver, map->key_ptr, *map->key_ptr, *map->buff_size ); +} + /** * efi_exit_boot_services() - Exit boot services * @handle: handle of the exiting image @@ -439,21 +444,24 @@ efi_status_t efi_exit_boot_services(void *handle, { efi_status_t status; - status = efi_get_memory_map(map); - - if (status != EFI_SUCCESS) - goto fail; - + efi_debug("Entered efi_exit_boot_services()\n"); + efi_debug("Memory map before calling priv_func():\n"); + efi_boot_memmap_report(map); status = priv_func(map, priv); + efi_debug("Memory map after calling priv_func():\n"); + efi_boot_memmap_report(map); if (status != EFI_SUCCESS) goto free_map; - if (efi_disable_pci_dma) + if (efi_disable_pci_dma) { + efi_debug("Calling efi_pci_disable_bridge_busmaster()\n"); efi_pci_disable_bridge_busmaster(); - + } + efi_debug("Calling efi_bs_call(exit_boot_services, 0x%p, 0x%lx)\n", handle, *map->key_ptr); status = efi_bs_call(exit_boot_services, handle, *map->key_ptr); if (status == EFI_INVALID_PARAMETER) { + efi_debug("efi_bs_call() returned %ld (EFI_INVALID_PARAMETER)\n", status); /* * The memory map changed between efi_get_memory_map() and * exit_boot_services(). Per the UEFI Spec v2.6, Section 6.4: @@ -468,6 +476,7 @@ efi_status_t efi_exit_boot_services(void *handle, * to get_memory_map() is expected to succeed here. */ *map->map_size = *map->buff_size; + efi_debug("Calling efi_bs_call() with get_memory_map\n"); status = efi_bs_call(get_memory_map, map->map_size, *map->map, @@ -475,27 +484,34 @@ efi_status_t efi_exit_boot_services(void *handle, map->desc_size, map->desc_ver); + efi_debug("Memory map after calling get_memory_map() again:\n"); + efi_boot_memmap_report(map); /* exit_boot_services() was called, thus cannot free */ if (status != EFI_SUCCESS) goto fail; - + efi_debug("Calling priv_func() again\n"); status = priv_func(map, priv); + efi_debug("Memory map after calling priv_func() again:\n"); + efi_boot_memmap_report(map); /* exit_boot_services() was called, thus cannot free */ if (status != EFI_SUCCESS) goto fail; + efi_debug("Calling (again!) efi_bs_call(exit_boot_services, 0x%p, 0x%lx)\n", handle, *map->key_ptr); status = efi_bs_call(exit_boot_services, handle, *map->key_ptr); } /* exit_boot_services() was called, thus cannot free */ if (status != EFI_SUCCESS) goto fail; - + efi_debug("Returning from efi_exit_boot_services() with EFI_SUCCESS\n"); return EFI_SUCCESS; free_map: + efi_debug("free_map: Calling efi_bs_call() with free_pool\n"); efi_bs_call(free_pool, *map->map); fail: + efi_debug("fail: efi_exit_boot_services() returns %ld\n", status); return status; } diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index b0ae0a454404..c2fd69ff8304 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -966,4 +966,6 @@ efi_enable_reset_attack_mitigation(void) { } void efi_retrieve_tpm2_eventlog(void); +void efi_boot_memmap_report(struct efi_boot_memmap *map); + #endif diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index fe567be0f118..4b66f511b050 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -207,6 +207,7 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv) { struct exit_boot_struct *p = priv; + efi_debug("Entered exit_boot_func() - updating map with virtual addresses\n"); /* * Update the memory map with virtual addresses. The function will also * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME @@ -214,7 +215,8 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, */ efi_get_virtmap(*map->map, *map->map_size, *map->desc_size, p->runtime_map, p->runtime_entry_count); - + efi_boot_memmap_report(map); + efi_debug("Returning after calling update_fdt_memmap()\n"); return update_fdt_memmap(p->new_fdt_addr, map); } @@ -243,6 +245,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, unsigned long fdt_addr, unsigned long fdt_size) { + unsigned long stall_delay = 10000000; unsigned long map_size, desc_size, buff_size; u32 desc_ver; unsigned long mmap_key; @@ -259,6 +262,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, map.key_ptr = &mmap_key; map.buff_size = &buff_size; + efi_debug("Entering allocate_new_fdt_and_exit_boot()\n"); /* * Get a copy of the current memory map that we will use to prepare * the input for SetVirtualAddressMap(). We don't have to worry about @@ -279,7 +283,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, efi_err("Unable to allocate memory for new device tree.\n"); goto fail; } - /* * Now that we have done our final memory allocation (and free) * we can get the memory map key needed for exit_boot_services(). @@ -287,11 +290,9 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, status = efi_get_memory_map(&map); if (status != EFI_SUCCESS) goto fail_free_new_fdt; - status = update_fdt((void *)fdt_addr, fdt_size, (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr, initrd_addr, initrd_size); - if (status != EFI_SUCCESS) { efi_err("Unable to construct new device tree.\n"); goto fail_free_new_fdt; @@ -302,18 +303,24 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, priv.runtime_entry_count = &runtime_entry_count; priv.new_fdt_addr = (void *)*new_fdt_addr; + efi_debug("Calling efi_exit_boot_services() with map:\n"); + efi_boot_memmap_report(&map); status = efi_exit_boot_services(handle, &map, &priv, exit_boot_func); - + efi_debug("Returned from efi_exit_boot_services()\n"); if (status == EFI_SUCCESS) { efi_set_virtual_address_map_t *svam; - - if (efi_novamap) + efi_debug("Preparing to do virtual address map\n"); + if (efi_novamap) { + efi_debug("Got 'novamap' so nothing to do\n"); return EFI_SUCCESS; + } /* Install the new virtual address map */ svam = efi_system_table->runtime->set_virtual_address_map; + efi_debug("Calling svam()\n"); status = svam(runtime_entry_count * desc_size, desc_size, desc_ver, runtime_map); + efi_debug("Returned from svam()\n"); /* * We are beyond the point of no return here, so if the call to @@ -322,6 +329,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, */ if (status != EFI_SUCCESS) { int l; + efi_debug("svam() failed with %ld\n", status); /* * Set the virtual address field of all @@ -336,17 +344,21 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, p->virt_addr = 0; } } + efi_debug("allocate_new_fdt_and_exit_boot() returning EFI_SUCCESS\n"); return EFI_SUCCESS; } efi_err("Exit boot services failed.\n"); fail_free_new_fdt: + efi_debug("fail_free_new_fdt: status=%ld\n", status); efi_free(MAX_FDT_SIZE, *new_fdt_addr); fail: + efi_debug("fail: status=%ld\n", status); efi_system_table->boottime->free_pool(runtime_map); - + efi_debug("Busy Wait so you can read the debug messages!"); + efi_bs_call(stall, stall_delay); return EFI_LOAD_ERROR; }