Message ID | 20230601120625.1843555-2-ilias.apalodimas@linaro.org |
---|---|
State | New |
Headers | show |
Series | [1/2] efi_loader: delete handle from events when a protocol is uninstalled | expand |
On 6/1/23 14:06, Ilias Apalodimas wrote: > A previous patch is fixing a problem where handles were added in > an event notification list, but were never deleted when the handle got > deleted. Add a test case which calls > - RegisterProtocolNotify > - IstallMultipleProtocolInterface > - UnIstallMultipleProtocolInterface > - LocateHandleBuffer(ByRegisterNotify) > The last call should return EFI_NOT_FOUND > > Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> > --- > Heinrich this is not rebased on top of > https://lore.kernel.org/u-boot/20230601070609.14977-1-heinrich.schuchardt@canonical.com/ > > .../efi_selftest_register_notify.c | 61 ++++++++++++++++++- > 1 file changed, 59 insertions(+), 2 deletions(-) > > diff --git a/lib/efi_selftest/efi_selftest_register_notify.c b/lib/efi_selftest/efi_selftest_register_notify.c > index ad763dd6cb8b..d133c7c50b71 100644 > --- a/lib/efi_selftest/efi_selftest_register_notify.c > +++ b/lib/efi_selftest/efi_selftest_register_notify.c > @@ -33,8 +33,14 @@ static efi_guid_t guid1 = > static efi_guid_t guid2 = > EFI_GUID(0xf909f2bb, 0x90a8, 0x0d77, > 0x94, 0x0c, 0x3e, 0xa8, 0xea, 0x38, 0xd6, 0x6f); > +static efi_guid_t guid3 = > + EFI_GUID(0xfa09f2cb, 0x70a8, 0x0d77, > + 0x9a, 0x2c, 0x31, 0x18, 0xca, 0x41, 0xa6, 0x6e); > + > static struct context context; > static struct efi_event *event; > +static struct efi_event *test_uninstall_event; > +static void *test_uninstall_key; > > /* > * Notification function, increments the notification count if parameter > @@ -63,6 +69,17 @@ static void EFIAPI notify(struct efi_event *event, void *context) > } > } > > +/* > + * Notification function, does nothing and is used to test UninstallProtocol > + * > + * @event notified event > + * @context pointer to the notification count > + */ > +static void EFIAPI test_uninstall_notify(struct efi_event *event, void *context) > +{ > + return; > +} > + > /* > * Setup unit test. > * > @@ -91,6 +108,21 @@ static int setup(const efi_handle_t img_handle, > return EFI_ST_FAILURE; > } > > + ret = boottime->create_event(EVT_NOTIFY_SIGNAL, You could use the existing notify function. > + TPL_CALLBACK, test_uninstall_notify, NULL, > + &test_uninstall_event); > + if (ret != EFI_SUCCESS) { > + efi_st_error("could not create event\n"); > + return EFI_ST_FAILURE; > + } > + > + ret = boottime->register_protocol_notify(&guid3, test_uninstall_event, > + &test_uninstall_key); I would prefer to use the same guid1 protocol. Deleting one handle should not remove the other handle from the handle queue if both have the same protocol installed. > + if (ret != EFI_SUCCESS) { > + efi_st_error("could not register event\n"); > + return EFI_ST_FAILURE; > + } > + > return EFI_ST_SUCCESS; > } > > @@ -121,8 +153,10 @@ static int teardown(void) > static int execute(void) > { > efi_status_t ret; > - efi_handle_t handle1 = NULL, handle2 = NULL; > - struct interface interface1, interface2; > + efi_handle_t handle1 = NULL, handle2 = NULL, handle3 = NULL; > + struct interface interface1, interface2, interface3; > + efi_uintn_t handle_count; > + efi_handle_t *handles; > > ret = boottime->install_protocol_interface(&handle1, &guid1, > EFI_NATIVE_INTERFACE, > @@ -224,6 +258,29 @@ static int execute(void) > return EFI_ST_FAILURE; > } > > + ret = boottime->install_protocol_interface(&handle3, &guid3, > + EFI_NATIVE_INTERFACE, > + &interface3); > + if (ret != EFI_SUCCESS) { > + efi_st_error("could not install interface\n"); > + return EFI_ST_FAILURE; > + } Please, check the number of invocations of the notify function. > + > + ret = boottime->uninstall_multiple_protocol_interfaces > + (handle3, &guid3, &interface3, NULL); > + if (ret != EFI_SUCCESS) { > + efi_st_error("UninstallMultipleProtocolInterfaces failed\n"); > + return EFI_ST_FAILURE; > + } And here again. We don't expect UninstallMultipleProtocolInterfaces() to trigger the event. Best regards Heinrich > + > + ret = boottime->locate_handle_buffer(BY_REGISTER_NOTIFY, NULL, > + test_uninstall_key, > + &handle_count, &handles); > + if (ret != EFI_NOT_FOUND) { > + efi_st_error("UninstallMultipleProtocolInterfaces failed to delete event handles\n"); > + return EFI_ST_FAILURE; > + } > + > return EFI_ST_SUCCESS; > } > > -- > 2.39.2 >
Hi Heinrich, [...] > > + * @event notified event > > + * @context pointer to the notification count > > + */ > > +static void EFIAPI test_uninstall_notify(struct efi_event *event, void *context) > > +{ > > + return; > > +} > > + > > /* > > * Setup unit test. > > * > > @@ -91,6 +108,21 @@ static int setup(const efi_handle_t img_handle, > > return EFI_ST_FAILURE; > > } > > > > + ret = boottime->create_event(EVT_NOTIFY_SIGNAL, > > You could use the existing notify function. > The reason I created a new one is that the current one calls locate_handle_buffer(). See below > > + TPL_CALLBACK, test_uninstall_notify, NULL, > > + &test_uninstall_event); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("could not create event\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > + ret = boottime->register_protocol_notify(&guid3, test_uninstall_event, > > + &test_uninstall_key); > > I would prefer to use the same guid1 protocol. Deleting one handle > should not remove the other handle from the handle queue if both have > the same protocol installed. > Unless I am missing something, that would not work. The notifier function will call locate_handle_buffer and will retrieve all handles. As a result the subsequent call will return EFI_NOT_FOUND. You've already sent a ptch covering that, the purpose of this one is check that the handler will be clearer from the events list if the protocol gets uninstalled. We could use guid2 but I do prefer habing distinct protocols for every test. > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("could not register event\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > return EFI_ST_SUCCESS; > > } > > > > @@ -121,8 +153,10 @@ static int teardown(void) > > static int execute(void) > > { > > efi_status_t ret; > > - efi_handle_t handle1 = NULL, handle2 = NULL; > > - struct interface interface1, interface2; > > + efi_handle_t handle1 = NULL, handle2 = NULL, handle3 = NULL; > > + struct interface interface1, interface2, interface3; > > + efi_uintn_t handle_count; > > + efi_handle_t *handles; > > > > ret = boottime->install_protocol_interface(&handle1, &guid1, > > EFI_NATIVE_INTERFACE, > > @@ -224,6 +258,29 @@ static int execute(void) > > return EFI_ST_FAILURE; > > } > > > > + ret = boottime->install_protocol_interface(&handle3, &guid3, > > + EFI_NATIVE_INTERFACE, > > + &interface3); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("could not install interface\n"); > > + return EFI_ST_FAILURE; > > + } > > Please, check the number of invocations of the notify function. > I can add that, but the tests already check that case in detail. > > + > > + ret = boottime->uninstall_multiple_protocol_interfaces > > + (handle3, &guid3, &interface3, NULL); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("UninstallMultipleProtocolInterfaces failed\n"); > > + return EFI_ST_FAILURE; > > + } > > And here again. We don't expect UninstallMultipleProtocolInterfaces() to > trigger the event. > ditto Thanks /Ilias > Best regards > > Heinrich > > > + > > + ret = boottime->locate_handle_buffer(BY_REGISTER_NOTIFY, NULL, > > + test_uninstall_key, > > + &handle_count, &handles); > > + if (ret != EFI_NOT_FOUND) { > > + efi_st_error("UninstallMultipleProtocolInterfaces failed to delete event handles\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > return EFI_ST_SUCCESS; > > } > > > > -- > > 2.39.2 > > >
Am 1. Juni 2023 21:32:04 MESZ schrieb Ilias Apalodimas <ilias.apalodimas@linaro.org>: >Hi Heinrich, > >[...] >> > + * @event notified event >> > + * @context pointer to the notification count >> > + */ >> > +static void EFIAPI test_uninstall_notify(struct efi_event *event, void *context) >> > +{ >> > + return; >> > +} >> > + >> > /* >> > * Setup unit test. >> > * >> > @@ -91,6 +108,21 @@ static int setup(const efi_handle_t img_handle, >> > return EFI_ST_FAILURE; >> > } >> > >> > + ret = boottime->create_event(EVT_NOTIFY_SIGNAL, >> >> You could use the existing notify function. >> > >The reason I created a new one is that the current one calls >locate_handle_buffer(). See below > >> > + TPL_CALLBACK, test_uninstall_notify, NULL, >> > + &test_uninstall_event); >> > + if (ret != EFI_SUCCESS) { >> > + efi_st_error("could not create event\n"); >> > + return EFI_ST_FAILURE; >> > + } >> > + >> > + ret = boottime->register_protocol_notify(&guid3, test_uninstall_event, >> > + &test_uninstall_key); >> >> I would prefer to use the same guid1 protocol. Deleting one handle >> should not remove the other handle from the handle queue if both have >> the same protocol installed. >> > >Unless I am missing something, that would not work. The notifier function >will call locate_handle_buffer and will retrieve all handles. As a result This would not match the specification. LocateHandle(ByRegistrationKey) must only retrieve at maximum a single handle per call irrespective of the queue size. LocateHandleBuffer() should do the same. Regards Heinrich >the subsequent call will return EFI_NOT_FOUND. You've already sent a ptch >covering that, the purpose of this one is check that the handler will be >clearer from the events list if the protocol gets uninstalled. >We could use guid2 but I do prefer habing distinct protocols for every >test. > >> > + if (ret != EFI_SUCCESS) { >> > + efi_st_error("could not register event\n"); >> > + return EFI_ST_FAILURE; >> > + } >> > + >> > return EFI_ST_SUCCESS; >> > } >> > >> > @@ -121,8 +153,10 @@ static int teardown(void) >> > static int execute(void) >> > { >> > efi_status_t ret; >> > - efi_handle_t handle1 = NULL, handle2 = NULL; >> > - struct interface interface1, interface2; >> > + efi_handle_t handle1 = NULL, handle2 = NULL, handle3 = NULL; >> > + struct interface interface1, interface2, interface3; >> > + efi_uintn_t handle_count; >> > + efi_handle_t *handles; >> > >> > ret = boottime->install_protocol_interface(&handle1, &guid1, >> > EFI_NATIVE_INTERFACE, >> > @@ -224,6 +258,29 @@ static int execute(void) >> > return EFI_ST_FAILURE; >> > } >> > >> > + ret = boottime->install_protocol_interface(&handle3, &guid3, >> > + EFI_NATIVE_INTERFACE, >> > + &interface3); >> > + if (ret != EFI_SUCCESS) { >> > + efi_st_error("could not install interface\n"); >> > + return EFI_ST_FAILURE; >> > + } >> >> Please, check the number of invocations of the notify function. >> > >I can add that, but the tests already check that case in detail. > >> > + >> > + ret = boottime->uninstall_multiple_protocol_interfaces >> > + (handle3, &guid3, &interface3, NULL); >> > + if (ret != EFI_SUCCESS) { >> > + efi_st_error("UninstallMultipleProtocolInterfaces failed\n"); >> > + return EFI_ST_FAILURE; >> > + } >> >> And here again. We don't expect UninstallMultipleProtocolInterfaces() to >> trigger the event. >> > >ditto > >Thanks >/Ilias >> Best regards >> >> Heinrich >> >> > + >> > + ret = boottime->locate_handle_buffer(BY_REGISTER_NOTIFY, NULL, >> > + test_uninstall_key, >> > + &handle_count, &handles); >> > + if (ret != EFI_NOT_FOUND) { >> > + efi_st_error("UninstallMultipleProtocolInterfaces failed to delete event handles\n"); >> > + return EFI_ST_FAILURE; >> > + } >> > + >> > return EFI_ST_SUCCESS; >> > } >> > >> > -- >> > 2.39.2 >> > >>
diff --git a/lib/efi_selftest/efi_selftest_register_notify.c b/lib/efi_selftest/efi_selftest_register_notify.c index ad763dd6cb8b..d133c7c50b71 100644 --- a/lib/efi_selftest/efi_selftest_register_notify.c +++ b/lib/efi_selftest/efi_selftest_register_notify.c @@ -33,8 +33,14 @@ static efi_guid_t guid1 = static efi_guid_t guid2 = EFI_GUID(0xf909f2bb, 0x90a8, 0x0d77, 0x94, 0x0c, 0x3e, 0xa8, 0xea, 0x38, 0xd6, 0x6f); +static efi_guid_t guid3 = + EFI_GUID(0xfa09f2cb, 0x70a8, 0x0d77, + 0x9a, 0x2c, 0x31, 0x18, 0xca, 0x41, 0xa6, 0x6e); + static struct context context; static struct efi_event *event; +static struct efi_event *test_uninstall_event; +static void *test_uninstall_key; /* * Notification function, increments the notification count if parameter @@ -63,6 +69,17 @@ static void EFIAPI notify(struct efi_event *event, void *context) } } +/* + * Notification function, does nothing and is used to test UninstallProtocol + * + * @event notified event + * @context pointer to the notification count + */ +static void EFIAPI test_uninstall_notify(struct efi_event *event, void *context) +{ + return; +} + /* * Setup unit test. * @@ -91,6 +108,21 @@ static int setup(const efi_handle_t img_handle, return EFI_ST_FAILURE; } + ret = boottime->create_event(EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, test_uninstall_notify, NULL, + &test_uninstall_event); + if (ret != EFI_SUCCESS) { + efi_st_error("could not create event\n"); + return EFI_ST_FAILURE; + } + + ret = boottime->register_protocol_notify(&guid3, test_uninstall_event, + &test_uninstall_key); + if (ret != EFI_SUCCESS) { + efi_st_error("could not register event\n"); + return EFI_ST_FAILURE; + } + return EFI_ST_SUCCESS; } @@ -121,8 +153,10 @@ static int teardown(void) static int execute(void) { efi_status_t ret; - efi_handle_t handle1 = NULL, handle2 = NULL; - struct interface interface1, interface2; + efi_handle_t handle1 = NULL, handle2 = NULL, handle3 = NULL; + struct interface interface1, interface2, interface3; + efi_uintn_t handle_count; + efi_handle_t *handles; ret = boottime->install_protocol_interface(&handle1, &guid1, EFI_NATIVE_INTERFACE, @@ -224,6 +258,29 @@ static int execute(void) return EFI_ST_FAILURE; } + ret = boottime->install_protocol_interface(&handle3, &guid3, + EFI_NATIVE_INTERFACE, + &interface3); + if (ret != EFI_SUCCESS) { + efi_st_error("could not install interface\n"); + return EFI_ST_FAILURE; + } + + ret = boottime->uninstall_multiple_protocol_interfaces + (handle3, &guid3, &interface3, NULL); + if (ret != EFI_SUCCESS) { + efi_st_error("UninstallMultipleProtocolInterfaces failed\n"); + return EFI_ST_FAILURE; + } + + ret = boottime->locate_handle_buffer(BY_REGISTER_NOTIFY, NULL, + test_uninstall_key, + &handle_count, &handles); + if (ret != EFI_NOT_FOUND) { + efi_st_error("UninstallMultipleProtocolInterfaces failed to delete event handles\n"); + return EFI_ST_FAILURE; + } + return EFI_ST_SUCCESS; }
A previous patch is fixing a problem where handles were added in an event notification list, but were never deleted when the handle got deleted. Add a test case which calls - RegisterProtocolNotify - IstallMultipleProtocolInterface - UnIstallMultipleProtocolInterface - LocateHandleBuffer(ByRegisterNotify) The last call should return EFI_NOT_FOUND Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> --- Heinrich this is not rebased on top of https://lore.kernel.org/u-boot/20230601070609.14977-1-heinrich.schuchardt@canonical.com/ .../efi_selftest_register_notify.c | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) -- 2.39.2