[PATCH 1/2] efi_loader: delete handle from events when a protocol is uninstalled
Ilias Apalodimas
ilias.apalodimas at linaro.org
Thu Jun 1 21:44:43 CEST 2023
[...]
> >
> > +/**
> > + * efi_handle_cleanup() - Clean the deleted handle from the various lists
> > + * @handle: handle to remove
> > + * @force: force removal even if protocols are still installed on the handle
> > + *
> > + * Return: status code
> > + */
> > +static void efi_handle_cleanup(efi_handle_t handle, bool force)
> > +{
> > + struct efi_register_notify_event *item, *next;
> > +
> > + if (!list_empty(&handle->protocols) || force)
>
> I guess the parameter force can be dropped from the interface.
>
'force' is here for a reason(see below), although the if is wrong.
The correct one is obviously
if (!list_empty(&handle->protocols) && !force)
....
> > + return;
>
> Please, return a failure code.
I am not sure why you want that, but I'll have a closer look
>
> > + /* The handle is about to be freed. Remove it from events */
> > + list_for_each_entry_safe(item, next, &efi_register_notify_events, link) {
> > + struct efi_protocol_notification *hitem, *hnext;
> > +
> > + list_for_each_entry_safe(hitem, hnext, &item->handles, link) {
> > + if (handle == hitem->handle) {
> > + list_del(&hitem->link);
> > + free(hitem);
> > + }
> > + }
> > + }
> > + /* The last protocol has been removed, delete the handle. */
> > + list_del(&handle->link);
> > + free(handle);
> > +}
> > +
> > /**
> > * efi_process_event_queue() - process event queue
> > */
> > @@ -627,8 +656,7 @@ void efi_delete_handle(efi_handle_t handle)
> > return;
> > }
>
> It would be safer to move the checks if a protocol interface can be
> removed from efi_uninstall_protocol() to efi_remove_protocol(). That way
> we are sure that no driver has attached to the protocols that we try to
> remove.
>
Yes it would, in fact I tried this on my initial patches and I mention it
on the patch description . However the selftests started failing. The reason
is that efi_reinstall_protocol_interface() does not remove the handle and we have
specific selftests for that. I don't really know or remember why that was
done like that, does the EFI spec describe this? I thought
UninstallProtocolInterface was always supposed to delete the handle if it
had no more protocols
> >
> > - list_del(&handle->link);
> > - free(handle);
> > + efi_handle_cleanup(handle, true);
>
> I don't think we should use a special treatment here. If the protocols
> cannot be deleted, because a driver has attached we should not delete
> the handle.
>
> The function should return a status code. Then efi_disk_delete_raw() can
> return an error for EVT_DM_PRE_REMOVE and stop the device from being
> deleted.
>
We agree again, but I am not trying to fix that atm. The reason for the
special check and the force flag is that efi_delete_handle() is already
doing something similar, which is cwnot optimal, but that's the current
state. It bails out only if the *handle* doesn't exist and doesn't care
if the protocols got removed. If you prefer having a bigger cleanup + fixes
let me know.
Thanks
/Ilias
> Best regards
>
> Heinrich
>
> > }
> >
> > /**
> > @@ -1396,11 +1424,8 @@ static efi_status_t EFIAPI efi_uninstall_protocol_interface
> > if (ret != EFI_SUCCESS)
> > goto out;
> >
> > - /* If the last protocol has been removed, delete the handle. */
> > - if (list_empty(&handle->protocols)) {
> > - list_del(&handle->link);
> > - free(handle);
> > - }
> > + /* Check if we have to purge the handle from various lists */
> > + efi_handle_cleanup(handle, false);
> > out:
> > return EFI_EXIT(ret);
> > }
> > @@ -2777,11 +2802,7 @@ efi_uninstall_multiple_protocol_interfaces_int(efi_handle_t handle,
> > i++;
> > }
> > if (ret == EFI_SUCCESS) {
> > - /* If the last protocol has been removed, delete the handle. */
> > - if (list_empty(&handle->protocols)) {
> > - list_del(&handle->link);
> > - free(handle);
> > - }
> > + efi_handle_cleanup(handle, false);
> > goto out;
> > }
> >
>
More information about the U-Boot
mailing list