mirror of
https://xff.cz/git/u-boot/
synced 2025-11-01 19:05:51 +01:00
efi_loader: make efi_delete_handle() follow the EFI spec
The EFI doesn't allow removal of handles, unless all hosted protocols are cleanly removed. Our efi_delete_handle() is a bit intrusive. Although it does try to delete protocols before removing a handle, it doesn't care if that fails. Instead it only returns an error if the handle is invalid. On top of that none of the callers of that function check the return code. So let's rewrite this in a way that fits the EFI spec better. Instead of forcing the handle removal, gracefully uninstall all the handle protocols. According to the EFI spec when the last protocol is removed the handle will be deleted. Also switch all the callers and check the return code. Some callers can't do anything useful apart from reporting an error. The disk related functions on the other hand, can prevent a medium that is being used by EFI from removal. The only function that doesn't check the result is efi_delete_image(). But that function needs a bigger rework anyway, so we can clean it up in the future Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
This commit is contained in:
committed by
Heinrich Schuchardt
parent
8505c0bb5c
commit
54edc37a22
@@ -59,6 +59,10 @@ static efi_handle_t current_image;
|
||||
static volatile gd_t *efi_gd, *app_gd;
|
||||
#endif
|
||||
|
||||
static efi_status_t efi_uninstall_protocol
|
||||
(efi_handle_t handle, const efi_guid_t *protocol,
|
||||
void *protocol_interface);
|
||||
|
||||
/* 1 if inside U-Boot code, 0 if inside EFI payload code */
|
||||
static int entry_count = 1;
|
||||
static int nesting_level;
|
||||
@@ -610,8 +614,8 @@ static efi_status_t efi_remove_all_protocols(const efi_handle_t handle)
|
||||
list_for_each_entry_safe(protocol, pos, &efiobj->protocols, link) {
|
||||
efi_status_t ret;
|
||||
|
||||
ret = efi_remove_protocol(handle, &protocol->guid,
|
||||
protocol->protocol_interface);
|
||||
ret = efi_uninstall_protocol(handle, &protocol->guid,
|
||||
protocol->protocol_interface);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
}
|
||||
@@ -622,19 +626,23 @@ static efi_status_t efi_remove_all_protocols(const efi_handle_t handle)
|
||||
* efi_delete_handle() - delete handle
|
||||
*
|
||||
* @handle: handle to delete
|
||||
*
|
||||
* Return: status code
|
||||
*/
|
||||
void efi_delete_handle(efi_handle_t handle)
|
||||
efi_status_t efi_delete_handle(efi_handle_t handle)
|
||||
{
|
||||
efi_status_t ret;
|
||||
|
||||
ret = efi_remove_all_protocols(handle);
|
||||
if (ret == EFI_INVALID_PARAMETER) {
|
||||
log_err("Can't remove invalid handle %p\n", handle);
|
||||
return;
|
||||
if (ret != EFI_SUCCESS) {
|
||||
log_err("Handle %p has protocols installed. Unable to delete\n", handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
list_del(&handle->link);
|
||||
free(handle);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user