In some cases, KUT guest might fail to exit boot services due to a possible memory map update that might have taken place between efi_get_memory_map() and efi_exit_boot_services() calls. As per UEFI spec 2.10 (Section 7.4.6 EFI_BOOT_SERVICES.ExitBootServices()), we need to keep trying to update the memory map and calls to exit boot services as long as case status is EFI_INVALID_PARAMETER. Signed-off-by: Pavan Kumar Paluri <papaluri@xxxxxxx> --- lib/efi.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/efi.c b/lib/efi.c index 8a74a22834a4..c98bc5c0a022 100644 --- a/lib/efi.c +++ b/lib/efi.c @@ -461,16 +461,35 @@ efi_status_t efi_main(efi_handle_t handle, efi_system_table_t *sys_tab) } #endif - /* + /* * Exit EFI boot services, let kvm-unit-tests take full control of the * guest */ status = efi_exit_boot_services(handle, &efi_bootinfo.mem_map); - if (status != EFI_SUCCESS) { + if (status != EFI_SUCCESS && status != EFI_INVALID_PARAMETER) { printf("Failed to exit boot services\n"); goto efi_main_error; } + /* + * There is a possibility that memory map might have changed + * between efi_get_memory_map() and efi_exit_boot_services in + * which case status is EFI_INVALID_PARAMETER. As per UEFI spec + * 2.10, we need to get the updated memory map and keep trying + * until status is not EFI_INVALID_PARAMETER. + */ + while (status == EFI_INVALID_PARAMETER) { + efi_get_memory_map(&efi_bootinfo.mem_map); + + status = efi_exit_boot_services(handle, + &efi_bootinfo.mem_map); + if (status != EFI_SUCCESS && + status != EFI_INVALID_PARAMETER) { + printf("Failed to exit boot services\n"); + goto efi_main_error; + } + } + /* Set up arch-specific resources */ status = setup_efi(&efi_bootinfo); if (status != EFI_SUCCESS) { -- 2.34.1