|
iPXE
|
EFI protocol opening and closing. More...
Go to the source code of this file.
Functions | |
| FILE_LICENCE (GPL2_OR_LATER_OR_UBDL) | |
| int | efi_open_untyped (EFI_HANDLE handle, EFI_GUID *protocol, void **interface) |
| Open (or test) protocol for ephemeral use. More... | |
| int | efi_open_unsafe_untyped (EFI_HANDLE handle, EFI_GUID *protocol, void **interface) |
| Open protocol for unsafe persistent use. More... | |
| void | efi_close_unsafe (EFI_HANDLE handle, EFI_GUID *protocol) |
| Close protocol opened for unsafe persistent use. More... | |
| int | efi_open_by_driver_untyped (EFI_HANDLE handle, EFI_GUID *protocol, void **interface) |
| Open protocol for persistent use by a driver. More... | |
| void | efi_close_by_driver (EFI_HANDLE handle, EFI_GUID *protocol) |
| Close protocol opened for persistent use by a driver. More... | |
| int | efi_open_by_child_untyped (EFI_HANDLE handle, EFI_GUID *protocol, EFI_HANDLE child, void **interface) |
| Open protocol for persistent use by a child controller. More... | |
| void | efi_close_by_child (EFI_HANDLE handle, EFI_GUID *protocol, EFI_HANDLE child) |
| Close protocol opened for persistent use by a child controller. More... | |
EFI protocol opening and closing.
The UEFI model for opening and closing protocols is broken by design and cannot be repaired.
Calling OpenProtocol() to obtain a protocol interface pointer does not, in general, provide any guarantees about the lifetime of that pointer. It is theoretically possible that the pointer has already become invalid by the time that OpenProtocol() returns the pointer to its caller. (This can happen when a USB device is physically removed, for example.)
Various UEFI design flaws make it occasionally necessary to hold on to a protocol interface pointer despite the total lack of guarantees that the pointer will remain valid.
The UEFI driver model overloads the semantics of OpenProtocol() to accommodate the use cases of recording a driver attachment (which is modelled as opening a protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes) and recording the existence of a related child controller (which is modelled as opening a protocol with EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER attributes).
The parameters defined for CloseProtocol() are not sufficient to allow the implementation to precisely identify the matching call to OpenProtocol(). While the UEFI model appears to allow for matched open and close pairs, this is merely an illusion. Calling CloseProtocol() will delete all matching records in the protocol open information tables.
Since the parameters defined for CloseProtocol() do not include the attributes passed to OpenProtocol(), this means that a matched open/close pair using EFI_OPEN_PROTOCOL_GET_PROTOCOL can inadvertently end up deleting the record that defines a driver attachment or the existence of a child controller. This in turn can cause some very unexpected side effects, such as allowing other UEFI drivers to start controlling hardware to which iPXE believes it has exclusive access. This rarely ends well.
To prevent this kind of inadvertent deletion, we establish a convention for four different types of protocol opening:
This convention ensures that the four types of open never overlap within the set of parameters defined for CloseProtocol(), and so a close of one type cannot inadvertently delete the record corresponding to a different type.
Definition in file efi_open.c.
| FILE_LICENCE | ( | GPL2_OR_LATER_OR_UBDL | ) |
| int efi_open_untyped | ( | EFI_HANDLE | handle, |
| EFI_GUID * | protocol, | ||
| void ** | interface | ||
| ) |
Open (or test) protocol for ephemeral use.
| handle | EFI handle |
| protocol | Protocol GUID |
| interface | Protocol interface pointer to fill in (or NULL to test) |
| rc | Return status code |
Definition at line 96 of file efi_open.c.
References assert(), EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::CloseProtocol, controller, EEFI, efi_image_handle, EFI_OPEN_PROTOCOL_GET_PROTOCOL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL, efi_systab, handle, if(), NULL, protocol, and rc.
| int efi_open_unsafe_untyped | ( | EFI_HANDLE | handle, |
| EFI_GUID * | protocol, | ||
| void ** | interface | ||
| ) |
Open protocol for unsafe persistent use.
| handle | EFI handle |
| protocol | Protocol GUID |
| interface | Protocol interface pointer to fill in |
| rc | Return status code |
Definition at line 180 of file efi_open.c.
References assert(), EFI_SYSTEM_TABLE::BootServices, controller, EEFI, efi_image_handle, EFI_OPEN_PROTOCOL_GET_PROTOCOL, efi_systab, handle, NULL, EFI_BOOT_SERVICES::OpenProtocol, protocol, and rc.
| void efi_close_unsafe | ( | EFI_HANDLE | handle, |
| EFI_GUID * | protocol | ||
| ) |
Close protocol opened for unsafe persistent use.
| handle | EFI handle |
| protocol | Protocol GUID |
| child | Child controller handle |
Definition at line 218 of file efi_open.c.
References assert(), EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::CloseProtocol, controller, efi_image_handle, efi_systab, handle, NULL, and protocol.
Referenced by efi_bofm_start(), nii_pci_close(), and nii_pci_open().
| int efi_open_by_driver_untyped | ( | EFI_HANDLE | handle, |
| EFI_GUID * | protocol, | ||
| void ** | interface | ||
| ) |
Open protocol for persistent use by a driver.
| handle | EFI handle |
| protocol | Protocol GUID |
| interface | Protocol interface pointer to fill in |
| rc | Return status code |
Definition at line 240 of file efi_open.c.
References assert(), EFI_SYSTEM_TABLE::BootServices, controller, EEFI, efi_image_handle, EFI_OPEN_PROTOCOL_BY_DRIVER, EFI_OPEN_PROTOCOL_EXCLUSIVE, efi_systab, handle, NULL, EFI_BOOT_SERVICES::OpenProtocol, protocol, and rc.
| void efi_close_by_driver | ( | EFI_HANDLE | handle, |
| EFI_GUID * | protocol | ||
| ) |
Close protocol opened for persistent use by a driver.
| handle | EFI handle |
| protocol | Protocol GUID |
Definition at line 278 of file efi_open.c.
References assert(), EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::CloseProtocol, controller, efi_image_handle, efi_systab, handle, NULL, and protocol.
Referenced by efi_file_install(), efi_file_uninstall(), efi_snp_probe(), efi_snp_remove(), efipci_start(), efipci_stop(), mnpnet_start(), mnpnet_stop(), nii_start(), nii_stop(), snpnet_start(), snpnet_stop(), usbio_close(), usbio_start(), and usbio_stop().
| int efi_open_by_child_untyped | ( | EFI_HANDLE | handle, |
| EFI_GUID * | protocol, | ||
| EFI_HANDLE | child, | ||
| void ** | interface | ||
| ) |
Open protocol for persistent use by a child controller.
| handle | EFI handle |
| protocol | Protocol GUID |
| child | Child controller handle |
| interface | Protocol interface pointer to fill in |
| rc | Return status code |
Definition at line 301 of file efi_open.c.
References assert(), EFI_SYSTEM_TABLE::BootServices, controller, EEFI, efi_image_handle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER, efi_systab, handle, NULL, EFI_BOOT_SERVICES::OpenProtocol, protocol, and rc.
| void efi_close_by_child | ( | EFI_HANDLE | handle, |
| EFI_GUID * | protocol, | ||
| EFI_HANDLE | child | ||
| ) |
Close protocol opened for persistent use by a child controller.
| handle | EFI handle |
| protocol | Protocol GUID |
| child | Child controller handle |
Definition at line 343 of file efi_open.c.
References assert(), EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::CloseProtocol, controller, efi_image_handle, efi_systab, handle, NULL, and protocol.
Referenced by efi_child_del().
1.8.15