diff options
author | Tom Rini <trini@konsulko.com> | 2023-07-15 11:19:11 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-07-15 11:19:11 -0400 |
commit | 3a7a17dbdc016e77627f62f5dc55819e1be09f9c (patch) | |
tree | 5526535fea4647d182018a7f54c404c68bf47d7c /lib/efi_loader/efi_boottime.c | |
parent | e6e67bb9e0a40f3eb3c87d16935192821987c3e0 (diff) | |
parent | 345a8b15acf228c4a429f6569c34cbc0232e76eb (diff) |
Merge tag 'efi-2023-10-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request efi-2023-10-rc1
Documentation:
* enhance UEFI anti-rollback documentation
EFI:
* Reconnect drivers if UninstallProtocol fails
* Prefer short device paths for boot options
* Fix error handling when updating boot options for block devices
Diffstat (limited to 'lib/efi_loader/efi_boottime.c')
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index d5065f296a..2ca7359f3e 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -97,6 +97,12 @@ static efi_status_t EFIAPI efi_disconnect_controller( efi_handle_t driver_image_handle, efi_handle_t child_handle); +static +efi_status_t EFIAPI efi_connect_controller(efi_handle_t controller_handle, + efi_handle_t *driver_image_handle, + struct efi_device_path *remain_device_path, + bool recursive); + /* Called on every callback entry */ int __efi_entry_check(void) { @@ -1298,7 +1304,7 @@ static efi_status_t efi_disconnect_all_drivers const efi_guid_t *protocol, efi_handle_t child_handle) { - efi_uintn_t number_of_drivers; + efi_uintn_t number_of_drivers, tmp; efi_handle_t *driver_handle_buffer; efi_status_t r, ret; @@ -1308,15 +1314,30 @@ static efi_status_t efi_disconnect_all_drivers return ret; if (!number_of_drivers) return EFI_SUCCESS; - ret = EFI_NOT_FOUND; + + tmp = number_of_drivers; while (number_of_drivers) { - r = EFI_CALL(efi_disconnect_controller( + ret = EFI_CALL(efi_disconnect_controller( handle, driver_handle_buffer[--number_of_drivers], child_handle)); - if (r == EFI_SUCCESS) - ret = r; + if (ret != EFI_SUCCESS) + goto reconnect; } + + free(driver_handle_buffer); + return ret; + +reconnect: + /* Reconnect all disconnected drivers */ + for (; number_of_drivers < tmp; number_of_drivers++) { + r = EFI_CALL(efi_connect_controller(handle, + &driver_handle_buffer[number_of_drivers], + NULL, true)); + if (r != EFI_SUCCESS) + EFI_PRINT("Failed to reconnect controller\n"); + } + free(driver_handle_buffer); return ret; } @@ -1352,18 +1373,26 @@ static efi_status_t efi_uninstall_protocol r = efi_search_protocol(handle, protocol, &handler); if (r != EFI_SUCCESS) goto out; + if (handler->protocol_interface != protocol_interface) + return EFI_NOT_FOUND; /* Disconnect controllers */ - efi_disconnect_all_drivers(efiobj, protocol, NULL); + r = efi_disconnect_all_drivers(efiobj, protocol, NULL); + if (r != EFI_SUCCESS) { + r = EFI_ACCESS_DENIED; + goto out; + } /* Close protocol */ list_for_each_entry_safe(item, pos, &handler->open_infos, link) { if (item->info.attributes == EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL || item->info.attributes == EFI_OPEN_PROTOCOL_GET_PROTOCOL || item->info.attributes == EFI_OPEN_PROTOCOL_TEST_PROTOCOL) - list_del(&item->link); + efi_delete_open_info(item); } + /* if agents didn't close the protocols properly */ if (!list_empty(&handler->open_infos)) { r = EFI_ACCESS_DENIED; + EFI_CALL(efi_connect_controller(handle, NULL, NULL, true)); goto out; } r = efi_remove_protocol(handle, protocol, protocol_interface); |