aboutsummaryrefslogtreecommitdiffstats
path: root/src/interface
Commit message (Collapse)AuthorAgeFilesLines
* [efi] Veto the Itautec Ip4ConfigDxe driveritautecMichael Brown2021-06-111-8/+10
| | | | | | | | | | | | | | | The Ip4ConfigDxe driver bug that was observed on Dell systems in commit 64b4452 ("[efi] Blacklist the Dell Ip4ConfigDxe driver") has also been observed on systems with a manufacturer name of "Itautec S.A.". The symptoms of the bug are identical: an attempt to call DisconnectController() on the LOM device handle will lock up the system. Fix by extending the veto to cover the Ip4ConfigDxe driver for this manufacturer. Debugged-by: Celso Viana <celso.vianna@gmail.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Provide an "initrd.magic" file for use by UEFI kernelsMichael Brown2021-05-211-0/+88
| | | | | | | | | | | | | | | | | | | | | | | Provide a file "initrd.magic" via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL that contains the initrd file as constructed for BIOS bzImage kernels (including injected files with CPIO headers constructed by iPXE). This allows BIOS and UEFI kernels to obtain the exact same initramfs image, by adding "initrd=initrd.magic" to the kernel command line. For example: #!ipxe kernel boot/vmlinuz initrd=initrd.magic initrd boot/initrd.img initrd boot/modules/e1000.ko /lib/modules/e1000.ko initrd boot/modules/af_packet.ko /lib/modules/af_packet.ko boot Do not include the "initrd.magic" file within the root directory listing, since doing so would break software such as wimboot that processes all files within the root directory. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Allow for non-image-backed virtual filesMichael Brown2021-05-211-69/+221
| | | | | | | | Restructure the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL implementation to allow for the existence of virtual files that are not simply backed by a single underlying image. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Show ACPI address space descriptor ranges in debug messagesMichael Brown2021-04-211-0/+3
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Always map full length of coherent DMA buffer allocationMichael Brown2021-04-201-1/+2
| | | | | | | | | | | | | | | The EFI PCI API takes a page count as the input to AllocateBuffer() but a byte count as the input to Map(). There is nothing in the UEFI specification that requires us to map exactly the allocated length, and no systems have yet been observed that will fail if the map length does not exactly match the allocated length. However, it is plausible that some implementations may fail if asked to map a length that does not match the length of the corresponding allocation. Avoid potential future problems by always mapping the full allocated length. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [xen] Avoid infinite loop on allocation failure in xenstore_response()Michael Brown2021-04-201-6/+6
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [linux] Fail at link time if building slirp.linux without libslirpMichael Brown2021-03-111-29/+3
| | | | | | | | | | | | | | | | | | | | The iPXE build system is constructed for a standalone codebase with no external dependencies, and does not have any equivalent of the standard userspace ./configure script. We currently check for the ability to include slirp/libslirp.h and conditionalise portions of linux_api.c on its presence. The actual slirp driver code is built unconditionally, as with all iPXE drivers. This currently leads to a silent runtime failure if attempting to use slirp.linux built on a system that was missing slirp/libslirp.h. Convert this to a link-time failure by deliberately omitting the relevant symbols from linux_api.c when slirp/libslirp.h is not present. This allows other builds (e.g. tap.linux or tests.linux) to succeed: the link-time failure will occur only if the slirp driver is included within the build target. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [linux] Do not assume that stat() works on sysfs filesMichael Brown2021-03-031-29/+20
| | | | | | | | Linux kernel 3.12 and earlier report a zero size via stat() for all ACPI table files in sysfs. There is no way to determine the file size other than by reading the file until EOF. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [linux] Validate length of ACPI table read from sysfsMichael Brown2021-03-031-0/+10
| | | | | | | | | | | | | Consumers of acpi_find() will assume that returned structures include a valid table header and that the length in the table header is correct. These assumptions are necessary when dealing with raw ACPI tables, since there exists no independent source of length information. Ensure that these assumptions are also valid for ACPI tables read from sysfs. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [linux] Use fstat() rather than statx()Michael Brown2021-03-032-8/+7
| | | | | | | | | | | | The statx() system call has a clean header file and a consistent layout, but was unfortunately added only in kernel 4.11. Using stat() or fstat() directly is extremely messy since glibc does not necessarily use the kernel native data structures. However, as the only current use case is to obtain the length of an open file, we can merely provide a wrapper that does precisely this. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [linux] Use generic sysfs mechanism to read SMBIOS tableMichael Brown2021-03-022-64/+86
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [linux] Use generic sysfs mechanism to read ACPI tablesMichael Brown2021-03-021-78/+21
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [linux] Add a generic function for reading files from sysfsMichael Brown2021-03-022-0/+123
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [linux] Free cached ACPI tables on shutdownMichael Brown2021-03-021-0/+22
| | | | | | | Free any cached ACPI tables for the sake of neatness (and a clean report from Valgrind). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [build] Fix building on older versions of gccMichael Brown2021-03-021-0/+3
| | | | | | | | Versions of gcc prior to 9.1 do not support the single-argument form of static_assert(). Fix by unconditionally defining a compatibility macro for the single file that uses this. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [slirp] Add libslirp driver for LinuxMichael Brown2021-03-021-0/+158
| | | | | | | | | | | | | | | | | | | Add a driver using libslirp to provide a virtual network interface without requiring root permissions on the host. This simplifies the process of running iPXE as a Linux userspace application with network access. For example: make bin-x86_64-linux/slirp.linux ./bin-x86_64-linux/slirp.linux --net slirp libslirp will provide a built-in emulated DHCP server and NAT router. Settings such as the boot filename may be controlled via command-line options. For example: ./bin-x86_64-linux/slirp.linux \ --net slirp,filename=http://192.168.0.1/boot.ipxe Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [linux] Provide ACPI settings via /sys/firmware/acpi/tablesMichael Brown2021-03-011-0/+173
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [acpi] Allow for platforms that provide ACPI tables individuallyMichael Brown2021-03-011-0/+1
| | | | | | | | | | | | | | | | The ACPI API currently expects platforms to provide access to a single contiguous ACPI table. Some platforms (e.g. Linux userspace) do not provide a convenient way to obtain the entire ACPI table, but do provide access to individual tables. All iPXE consumers of the ACPI API require access only to individual tables. Redefine the internal API to make acpi_find() an API method, with all existing implementations delegating to the current RSDT-based implementation. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [linux] Use host glibc system call wrappersMichael Brown2021-02-2810-8/+419
| | | | | | | | | | | | | | | | | | | | | | When building as a Linux userspace application, iPXE currently implements its own system calls to the host kernel rather than relying on the host's C library. The output binary is statically linked and has no external dependencies. This matches the general philosophy of other platforms on which iPXE runs, since there are no external libraries available on either BIOS or UEFI bare metal. However, it would be useful for the Linux userspace application to be able to link against host libraries such as libslirp. Modify the build process to perform a two-stage link: first picking out the requested objects in the usual way from blib.a but with relocations left present, then linking again with a helper object to create a standard hosted application. The helper object provides the standard main() entry point and wrappers for the Linux system calls required by the iPXE Linux drivers and interface code. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Record cached DHCPACK from loaded image's device handle, if presentMichael Brown2021-02-172-0/+98
| | | | | | | | | | | Record the cached DHCPACK obtained from the EFI_PXE_BASE_CODE_PROTOCOL instance installed on the loaded image's device handle, if present. This allows a chainloaded UEFI iPXE to reuse the IPv4 address and DHCP options previously obtained by the built-in PXE stack, as is already done for a chainloaded BIOS iPXE. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Defer autoboot link-layer address and autoexec script probingMichael Brown2021-02-171-6/+20
| | | | | | | | | | | | | The code to detect the autoboot link-layer address and to load the autoexec script currently runs before the call to initialise() and so has to function without a working heap. This requirement can be relaxed by deferring this code to run via an initialisation function. This gives the code a normal runtime environment, but still invokes it early enough to guarantee that the original loaded image device handle has not yet been invalidated. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Split out autoexec script portions of efi_autoboot.cMichael Brown2021-02-173-189/+214
| | | | | | | | | | | The "autoboot device" and "autoexec script" functionalities in efi_autoboot.c are unrelated except in that they both need to be invoked by efiprefix.c before device drivers are loaded. Split out the autoexec script portions to a separate file to avoid potential confusion. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Fix erroneous comparison of a pointer against userptr_tMichael Brown2021-02-031-1/+1
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Use EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL if availableMichael Brown2021-01-271-11/+66
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The original EFI_SIMPLE_TEXT_INPUT_PROTOCOL is not technically required to handle the use of the Ctrl key, and the long-obsolete EFI 1.10 specification lists only backspace, tab, linefeed, and carriage return as required. Some particularly brain-dead vendor UEFI firmware implementations dutifully put in the extra effort of ensuring that all other control characters (such as Ctrl-C) are impossible to type via EFI_SIMPLE_TEXT_INPUT_PROTOCOL. Current versions of the UEFI specification mandate that the console input handle must support both EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL, the latter of which at least provides access to modifier key state. Unlike EFI_SIMPLE_TEXT_INPUT_PROTOCOL, the pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance does not appear within the EFI system table and must therefore be opened explicitly. The UEFI specification provides no safe way to do so, since we cannot open the handle BY_DRIVER or BY_CHILD_CONTROLLER and so nothing guarantees that this pointer will remain valid for the lifetime of iPXE. We must simply hope that no UEFI firmware implementation ever discovers a motivation for reinstalling the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. Use EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL if available, falling back to the existing EFI_SIMPLE_TEXT_PROTOCOL otherwise. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Fix misleading debug messageMichael Brown2021-01-261-1/+2
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Fix use of uninitialised variableMichael Brown2021-01-261-0/+3
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Automatically load "/autoexec.ipxe" when booted from a filesystemMichael Brown2021-01-251-10/+200
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When booting iPXE from a filesystem (e.g. a FAT-formatted USB key) it can be useful to have an iPXE script loaded automatically from the same filesystem. Compared to using an embedded script, this has the advantage that the script can be edited without recompiling the iPXE binary. For the BIOS version of iPXE, loading from a filesystem is handled using syslinux (or isolinux) which allows the script to be passed to the iPXE .lkrn image as an initrd. For the UEFI version of iPXE, the platform firmware loads the iPXE .efi image directly and there is currently no equivalent of the BIOS initrd mechanism. Add support for automatically loading a file "autoexec.ipxe" (if present) from the root of the filesystem containing the UEFI iPXE binary. A combined BIOS and UEFI image for a USB key can be created using e.g. ./util/genfsimg -o usbkey.img -s myscript.ipxe \ bin-x86_64-efi/ipxe.efi bin/ipxe.lkrn The file "myscript.ipxe" would appear as "autoexec.ipxe" on the USB key, and would be loaded automatically on both BIOS and UEFI systems. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Leave asynchronous USB endpoints open until device is removedMichael Brown2021-01-031-11/+13
| | | | | | | | | | | | | | | | | | | | Some UEFI device drivers will react to an asynchronous USB transfer failure by dubiously terminating the scheduled transfer from within the completion handler. We already have code from commit fbb776f ("[efi] Leave USB endpoint descriptors in existence until device is removed") that avoids freeing memory in this situation, in order to avoid use-after-free bugs. This is not sufficient to avoid potential problems, since with an xHCI controller the act of closing the endpoint requires issuing a command and awaiting completion via the event ring, which may in turn dispatch further USB transfer completion events. Avoid these problems by leaving the USB endpoint open (but with the refill timer stopped) until the device is finally removed, as is already done for control and bulk transfers. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Use segment and bus number to identify PCI root bridge I/O protocolv1.21.1Michael Brown2020-12-311-4/+68
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There may be multiple instances of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL for a single PCI segment. Use the bus number range descriptor from the ACPI resource list to identify the correct protocol instance. There is some discrepancy between the ACPI and UEFI specifications regarding the interpretation of values within the ACPI resource list. The ACPI specification defines the min/max field values to be within the secondary (device-side) address space, and defines the offset field value as "the offset that must be added to the address on the secondary side to obtain the address on the primary side". The UEFI specification states instead that the offset field value is the "offset to apply to the starting address to convert it to a PCI address", helpfully omitting to clarify whether "to apply" in this context means "to add" or "to subtract". The implication of the wording is also that the "starting address" is not already a "PCI address" and must therefore be a host-side address rather than the ACPI-defined device-side address. Code comments in the EDK2 codebase seem to support the latter (non-ACPI) interpretation of these ACPI structures. For example, in the PciHostBridgeDxe driver there can be found the comment Macros to translate device address to host address and vice versa. According to UEFI 2.7, device address = host address + translation offset. along with a pair of macros TO_HOST_ADDRESS() and TO_DEVICE_ADDRESS() which similarly negate the sense of the "translation offset" from the definition found in the ACPI specification. The existing logic in efipci_ioremap() (based on a presumed-working externally contributed patch) applies the non-ACPI interpretation: it assumes that min/max field values are host-side addresses and that the offset field value is negated. Match this existing logic by assuming that min/max field values are host-side bus numbers. (The bus number offset value is therefore not required and so can be ignored.) As noted in commit 9b25f6e ("[efi] Fall back to assuming identity mapping of MMIO address space"), some systems seem to fail to provide MMIO address space descriptors. Assume that some systems may similarly fail to provide bus number range descriptors, and fall back in this situation to assuming that matching on segment number alone is sufficient. Testing any of this is unfortunately impossible without access to esoteric hardware that actually uses non-zero translation offsets. Originally-implemented-by: Thomas Walker <twalker@twosigma.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [smbios] Add support for the 64-bit SMBIOS3 entry pointMichael Brown2020-12-292-18/+35
| | | | | | | Support UEFI systems that provide only 64-bit versions of the SMBIOS entry point. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Allow for longer device paths in debug messagesb1f6c1c42020-12-291-1/+1
| | | | | Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Allow EFI_USB_IO_PROTOCOL interfaces to be nullified and leakedMichael Brown2020-12-172-9/+179
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Skip interface uninstallation during shutdownMichael Brown2020-12-174-18/+23
| | | | | | | | | | | | | | | | | | | | | | iPXE seems to be almost alone in the UEFI world in attempting to shut down cleanly, free resources, and leave hardware in a well-defined reset state before handing over to the booted operating system. The UEFI driver model does allow for graceful shutdown via uninstallation of protocol interfaces. However, virtually no other UEFI drivers do this, and the external code paths that react to uninstallation are consequently poorly tested. This leads to a proliferation of bugs found in UEFI implementations in the wild, as described in commits such as 1295b4a ("[efi] Allow initialisation via SNP interface even while claimed") or b6e2ea0 ("[efi] Veto the HP XhciDxe Driver"). Try to avoid triggering such bugs by unconditionally skipping the protocol interface uninstallation during UEFI boot services shutdown, leaving the interfaces present but nullified and deliberately leaking the containing memory. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Nullify interfaces unconditionally on error and shutdown pathsMichael Brown2020-12-174-16/+16
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Avoid using potentially uninitialised driver name in veto checksMichael Brown2020-12-081-2/+4
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Veto the HP XhciDxe DriverMichael Brown2020-11-301-0/+46
| | | | | | | | | | | | The HP XhciDxe driver (observed on an HP EliteBook 840 G6) does not respond correctly to driver disconnection, and will leave the PciIo protocol instance opened with BY_DRIVER attributes even after returning successfully from its Stop() method. This prevents iPXE from subsequently connecting to the PCI device handle. Veto this driver if the iPXE build includes a native xHCI driver. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Allow vetoing of drivers that cannot be unloadedMichael Brown2020-11-302-8/+311
| | | | | | | | | | | | | | | | Some UEFI drivers (observed with the "Usb Xhci Driver" on an HP EliteBook) are particularly badly behaved: they cannot be unloaded and will leave handles opened with BY_DRIVER attributes even after disconnecting the driver, thereby preventing a replacement iPXE driver from opening the handle. Allow such drivers to be vetoed by falling back to a brute-force mechanism that will disconnect the driver from all handles, uninstall the driver binding protocol (to prevent it from attaching to any new handles), and finally close any stray handles that the vetoed driver has left open. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Provide manufacturer and driver names to all veto checking methodsMichael Brown2020-11-301-19/+40
| | | | | | | Most veto checks are likely to use the manufacturer name and driver name, so pass these as parameters to minimise code duplication. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Split out dbg_efi_opener() as a standalone functionMichael Brown2020-11-301-15/+24
| | | | | | | Allow external code to dump the information for an opened protocol information entry via DBG_EFI_OPENER() et al. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dma] Provide dma_umalloc() for allocating large DMA-coherent buffersMichael Brown2020-11-291-0/+34
| | | | | | | | | | | | | | Some devices (e.g. xHCI USB host controllers) may require the use of large areas of host memory for private use by the device. These allocations cannot be satisfied from iPXE's limited heap space, and so are currently allocated using umalloc() which will allocate external system memory (and alter the system memory map as needed). Provide dma_umalloc() to provide such allocations as part of the DMA API, since there is otherwise no way to guarantee that the allocated regions are usable for coherent DMA. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Avoid requesting zero-length DMA mappingsMichael Brown2020-11-291-12/+16
| | | | | | | | | The UEFI specification does not prohibit zero-length DMA mappings. However, there is a reasonable chance that at least one implementation will treat it as an invalid parameter. As a precaution, avoid calling EFI_PCI_IO_PROTOCOL.Map() with a length of zero. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dma] Move I/O buffer DMA operations to iobuf.hMichael Brown2020-11-281-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Include a potential DMA mapping within the definition of an I/O buffer, and move all I/O buffer DMA mapping functions from dma.h to iobuf.h. This avoids the need for drivers to maintain a separate list of DMA mappings for each I/O buffer that they may handle. Network device drivers typically do not keep track of transmit I/O buffers, since the network device core already maintains a transmit queue. Drivers will typically call netdev_tx_complete_next() to complete a transmission without first obtaining the relevant I/O buffer pointer (and will rely on the network device core automatically cancelling any pending transmissions when the device is closed). To allow this driver design approach to be retained, update the netdev_tx_complete() family of functions to automatically perform the DMA unmapping operation if required. For symmetry, also update the netdev_rx() family of functions to behave the same way. As a further convenience for drivers, allow the network device core to automatically perform DMA mapping on the transmit datapath before calling the driver's transmit() method. This avoids the need to introduce a mapping error handling code path into the typically error-free transmit methods. With these changes, the modifications required to update a typical network device driver to use the new DMA API are fairly minimal: - Allocate and free descriptor rings and similar coherent structures using dma_alloc()/dma_free() rather than malloc_phys()/free_phys() - Allocate and free receive buffers using alloc_rx_iob()/free_rx_iob() rather than alloc_iob()/free_iob() - Calculate DMA addresses using dma() or iob_dma() rather than virt_to_bus() - Set a 64-bit DMA mask if needed using dma_set_mask_64bit() and thereafter eliminate checks on DMA address ranges - Either record the DMA device in netdev->dma, or call iob_map_tx() as part of the transmit() method - Ensure that debug messages use virt_to_phys() when displaying "hardware" addresses Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dma] Record DMA device as part of DMA mapping if neededMichael Brown2020-11-281-12/+13
| | | | | | | Allow for dma_unmap() to be called by code other than the DMA device driver itself. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [dma] Modify DMA API to simplify calculation of medial addressesMichael Brown2020-11-251-3/+3
| | | | | | | | | | | | | | | | | Redefine the value stored within a DMA mapping to be the offset between physical addresses and DMA addresses within the mapped region. Provide a dma() wrapper function to calculate the DMA address for any pointer within a mapped region, thereby simplifying the use cases when a device needs to be given addresses other than the region start address. On a platform using the "flat" DMA implementation the DMA offset for any mapped region is always zero, with the result that dma_map() can be optimised away completely and dma() reduces to a straightforward call to virt_to_phys(). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Report correct error when failing to unload a vetoed driverMichael Brown2020-11-241-0/+1
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Allow initialisation via SNP interface even while claimedMichael Brown2020-11-231-7/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | iPXE will currently fail all SNP interface methods with EFI_NOT_READY while the network devices are claimed for use by iPXE's own network stack. As of commit c70b3e0 ("[efi] Always enable recursion when calling ConnectController()"), this exposes latent UEFI firmware bugs on some systems at the point of calling ExitBootServices(). With recursion enabled, the MnpDxe driver will immediately attempt to consume the SNP protocol instance provided by iPXE. Since the network devices are claimed by iPXE at this point, the calls by MnpDxe to Start() and Initialize() will both fail with EFI_NOT_READY. This unfortunately triggers a broken error-handling code path in the Ip6Dxe driver. Specifically: Ip6DriverBindingStart() will call Ip6CreateService(), which will call Ip6ServiceConfigMnp(), which will return an error. The subsequent error handling code path in Ip6CreateService() simply calls Ip6CleanService(). The code in Ip6CleanService() will attempt to leave the all-nodes multicast group, which will fail since the group was never joined. This will result in Ip6CleanService() returning an error and omitting most of the required clean-up operations. In particular, the MNP protocol instance will remain opened with BY_DRIVER attributes even though the Ip6Dxe driver start method has failed. When ExitBootServices() is eventually called, iPXE will attempt to uninstall the SNP protocol instance. This results in the UEFI core calling Ip6DriverBindingStop(), which will fail since there is no EFI_IP6_SERVICE_BINDING_PROTOCOL instance installed on the handle. A failure during a call to UninstallMultipleProtocolInterfaces() will result in the UEFI core attempting to reinstall any successfully uninstalled protocols. This is an intrinsically unsafe operation, and represents a fundamental design flaw in UEFI. Failure code paths cannot be required to themselves handle failures, since there is no well-defined correct outcome of such a situation. With a current build of OVMF, this results in some unexpected debug messages occurring at the time that the loaded operating system calls ExitBootServices(). With the UEFI firmware in Hyper-V, the result is an immediate reboot. Work around these UEFI design and implementation flaws by allowing the calls to our EFI_SIMPLE_NETWORK_PROTOCOL instance's Start() and Initialize() methods to return success even when the network devices are claimed for exclusive use by iPXE. This is sufficient to allow MnpDxe to believe that it has successfully initialised the device, and thereby avoids the problematic failure code paths in Ip6Dxe. Debugged-by: Aaron Heusser <aaron_heusser@hotmail.com> Debugged-by: Pico Mitchell <pico@randomapplications.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Avoid dropping below TPL as at entry to iPXEMichael Brown2020-11-207-71/+99
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | iPXE will currently drop to TPL_APPLICATION whenever the current system time is obtained via currticks(), since the system time mechanism relies on a timer that can fire only when the TPL is below TPL_CALLBACK. This can cause unexpected behaviour if the system time is obtained in the middle of an API call into iPXE by external code. For example, MnpDxe sets up a 10ms periodic timer running at TPL_CALLBACK to poll the underling EFI_SIMPLE_NETWORK_PROTOCOL device for received packets. If the resulting poll within iPXE happens to hit a code path that requires obtaining the current system time (e.g. due to reception of an STP packet, which affects iPXE's blocked link timer), then iPXE will end up temporarily dropping to TPL_APPLICATION. This can potentially result in retriggering the MnpDxe periodic timer, causing code to be unexpectedly re-entered. Fix by recording the external TPL at any entry point into iPXE and dropping only as far as this external TPL, rather than dropping unconditionally to TPL_APPLICATION. The side effect of this change is that iPXE's view of the current system time will be frozen for the duration of any API calls made into iPXE by external code at TPL_CALLBACK or above. Since any such external code is already responsible for allowing execution at TPL_APPLICATION to occur, then this should not cause a problem in practice. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Rename efi_blacklist to efi_vetoMichael Brown2020-11-072-48/+47
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [efi] Provide DMA operations for EFI PCI devicesMichael Brown2020-11-051-0/+237
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [malloc] Rename malloc_dma() to malloc_phys()Michael Brown2020-11-051-3/+3
| | | | | | | | | | | | The malloc_dma() function allocates memory with specified physical alignment, and is typically (though not exclusively) used to allocate memory for DMA. Rename to malloc_phys() to more closely match the functionality, and to create name space for functions that specifically allocate and map DMA-capable buffers. Signed-off-by: Michael Brown <mcb30@ipxe.org>