diff options
author | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2019-06-02 20:02:32 +0200 |
---|---|---|
committer | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2019-06-04 22:09:26 +0200 |
commit | 120ff7ba68df265a8b96c5c6131b579ce722a7a5 (patch) | |
tree | 6ca13fa4f6bc980b3314cb71dfde99d67e19d2da | |
parent | 25e6fb5e93194d84c4b93fb3ab9d93d2157923dd (diff) | |
download | u-boot-120ff7ba68df265a8b96c5c6131b579ce722a7a5.tar.gz u-boot-120ff7ba68df265a8b96c5c6131b579ce722a7a5.tar.xz u-boot-120ff7ba68df265a8b96c5c6131b579ce722a7a5.zip |
efi_loader: close protocols in UnloadImage()
When UnloadImage() is called all protocols opened by the image have to be
closed.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index fed8d47ade..78c6076e28 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2791,12 +2791,46 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, * @image_obj: handle of the loaded image * @loaded_image_protocol: loaded image protocol */ -static void efi_delete_image(struct efi_loaded_image_obj *image_obj, - struct efi_loaded_image *loaded_image_protocol) +static efi_status_t efi_delete_image + (struct efi_loaded_image_obj *image_obj, + struct efi_loaded_image *loaded_image_protocol) { + struct efi_object *efiobj; + efi_status_t r, ret = EFI_SUCCESS; + +close_next: + list_for_each_entry(efiobj, &efi_obj_list, link) { + struct efi_handler *protocol; + + list_for_each_entry(protocol, &efiobj->protocols, link) { + struct efi_open_protocol_info_item *info; + + list_for_each_entry(info, &protocol->open_infos, link) { + if (info->info.agent_handle != + (efi_handle_t)image_obj) + continue; + r = EFI_CALL(efi_close_protocol + (efiobj, protocol->guid, + info->info.agent_handle, + info->info.controller_handle + )); + if (r != EFI_SUCCESS) + ret = r; + /* + * Closing protocols may results in further + * items being deleted. To play it safe loop + * over all elements again. + */ + goto close_next; + } + } + } + efi_free_pages((uintptr_t)loaded_image_protocol->image_base, efi_size_in_pages(loaded_image_protocol->image_size)); efi_delete_handle(&image_obj->header); + + return ret; } /** |