[efi] Inhibit our driver Start() method during disconnection attempts
Some HP BIOSes (observed with a Z840) seem to attempt to connect our
drivers in the middle of our call to DisconnectController(). The
precise chain of events is unclear, but the symptom is that we see
several calls to our Supported() and Start() methods, followed by a
system lock-up.
Work around this dubious BIOS behaviour by explicitly failing calls to
our Start() method while we are in the middle of attempting to
disconnect drivers.
Reported-by: Jordan Wright <jordan.m.wright@disney.com>
Debugged-by: Adrian Lucrèce Céleste <adrianlucrececeleste@airmail.cc>
Debugged-by: Christian Nilsson <nikize@gmail.com>
Tested-by: Jordan Wright <jordan.m.wright@disney.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[build] Exclude selected directories from Secure Boot builds
When submitting binaries for UEFI Secure Boot signing, certain
known-dubious subsystems (such as 802.11 and NFS) must be excluded
from the build. Mark the directories containing these subsystems as
insecure, and allow the build target to include an explicit "security
flag" (a literal "-sb" appended to the build platform) to exclude
these source directories from the build process.
For example:
make bin-x86_64-efi-sb/ipxe.efi
will build iPXE with all code from the 802.11 and NFS subsystems
excluded from the build.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[efi] Continue to connect remaining handles after connection errors
Some UEFI BIOSes will deliberately break the implementation of
ConnectController() to return errors for devices that have been
"disabled" via the BIOS setup screen. (As an added bonus, such BIOSes
may return garbage EFI_STATUS values such as 0xff.)
Work around these broken UEFI BIOSes by ignoring failures and
continuing to attempt to connect any remaining handles.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[efi] Match behaviour of SnpDxe for truncated received packets
The UEFI specification does not state whether or not a return value of
EFI_BUFFER_TOO_SMALL from the SNP Receive() method should follow the
usual EFI API behaviour of allowing the caller to retry the request
with an increased buffer size.
Examination of the SnpDxe driver in EDK2 suggests that Receive() will
just return the truncated packet (complete with any requested
link-layer header fields), so match this behaviour.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[efi] Check buffer length for packets retrieved via our SNP protocol
We do not currently check the length of the caller's buffer for
received packets. This creates a potential buffer overrun when iPXE
is being used via the SNP or UNDI protocols.
Fix by checking the buffer length and correctly returning the required
length and an EFI_BUFFER_TOO_SMALL error.
Reported-by: Paul McMillan <paul.mcmillan@oracle.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Expose the underlying hardware address as a setting. For IPoIB
devices, this provides scripts with access to the Infiniband GUID.
Requested-by: Allen, Benjamin S. <bsallen@alcf.anl.gov>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[peerdist] Gather and report peer statistics during download
Record and report the number of peers (calculated as the maximum
number of peers discovered for a block's segment at the time that the
block download is complete), and the percentage of blocks retrieved
from peers rather than from the origin server.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[monojob] Check for job progress only once per timer tick
Checking for job progress is essentially a user interface activity,
and can safely be performed only once per timer tick (as is already
done with checking for keypresses).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[netdevice] Cancel all pending transmissions on any transmit error
Some external code (such as the UEFI UNDI driver for the Realtek USB
NIC on a Microsoft Surface Book) will block during transmission
attempts and can take several seconds to report a transmit error. If
there is a large queue of pending transmissions, then the accumulated
time from a series of such failures can easily exceed the EFI watchdog
timeout, resulting in what appears to be a system lockup followed by a
reboot.
Work around this problem by immediately cancelling any pending
transmissions as soon as any transmit error occurs.
The only expected transmit error under normal operation is ENOBUFS
arising when the hardware transmit queue is full. By definition, this
can happen only for drivers that do not utilise deferred
transmissions, and so this new behaviour will not affect these
drivers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The SnpDxe driver raises the task priority level to TPL_CALLBACK when
calling the UNDI entry point. This does not appear to be a documented
requirement, but we should probably match the behaviour of SnpDxe to
minimise surprises to third party code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The tap driver can retrieve a potentially unlimited number of packets
in a single poll. This can lead to heap exhaustion under heavy load.
Fix by imposing an artificial receive quota (as already used in other
drivers without natural receive limits).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[malloc] Avoid false positive warnings from valgrind
Calling discard_cache() is likely to result in a call to
free_memblock(), which will call valgrind_make_blocks_noaccess()
before returning. This causes valgrind to report an invalid read on
the next iteration through the loop in alloc_memblock().
Fix by explicitly calling valgrind_make_blocks_defined() after
discard_cache() returns. Also call valgrind_make_blocks_noaccess()
before calling discard_cache(), to guard against free list corruption
while executing cache discarders.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[romprefix] Avoid unaligned accesses within ROM headers
Ensure that all headers (PCI, UNDI, PnP, iPXE) are aligned to at least
four bytes, so that all accesses to header fields will be correctly
aligned even when reading directly from the expansion ROM BAR.
Reported-by: Peter von Konigsmark <peter@exablaze.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[shell] Enable "shell" command even when BANNER_TIMEOUT is zero
Setting BANNER_TIMEOUT to zero removes the only symbol reference to
shell.o, causing the "shell" command to become unavailable.
Add SHELL_CMD in config/general.h (enabled by default) which will
explicitly drag in shell.o regardless of the value of BANNER_TIMEOUT.
Reported-by: Julian Brost <julian@0x4a42.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[hyperv] Do not steal ownership from the Gen 2 UEFI firmware
We must not steal ownership from the Gen 2 UEFI firmware, since doing
so will cause an immediate system crash (most likely in the form of a
reboot).
This problem was masked before commit a0f6e75 ("[hyperv] Do not fail
if guest OS ID MSR is already set"), since prior to that commit we
would always fail if we found any non-zero guest OS identity. We now
accept a non-zero previous guest OS identity in order to allow for
situations such as chainloading from iPXE to another iPXE, and as a
prerequisite for commit b91cc98 ("[hyperv] Cope with Windows Server
2016 enlightenments").
A proper fix would be to reverse engineer the UEFI protocols exposed
within the Hyper-V Gen 2 firmware and use these to bind to the VMBus
device representing the network connection, (with the native Hyper-V
driver moved to become a BIOS-only feature).
As an interim solution, fail to initialise the native Hyper-V driver
if we detect the guest OS identity known to be used by the Gen 2 UEFI
firmware. This will cause the standard all-drivers build (ipxe.efi)
to fall back to using the SNP driver.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[build] Fix ARM32 EFI builds with current EDK2 headers
EDK2 commit 6440385 ("MdePkg/Include: Add enumeration size checks to
Base.h") enforced the UEFI specification mandate that enums should
always be 32 bits. This revealed a latent bug in iPXE, which does not
build with -fno-short-enums.
Fix by adding -fno-short-enums to CFLAGS for ARM32 EFI builds.
Reported-by: Benjamin S. Allen <bsallen@alcf.anl.gov>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[build] Fix use of inline assembly on GCC 4.8 ARM64 builds
The inline assembly used in include/errno.h to generate the einfo
blocks requires the ability to generate an immediate constant with no
immediate-value prefix (such as the dollar sign for x86 assembly).
We currently achieve this via the undocumented "%c0" form of operand.
This causes an "invalid operand prefix" error on GCC 4.8 for ARM64
builds.
Fix by switching to the equally undocumented "%a0" form of operand,
which appears to work correctly on all tested versions of GCC.
Reported-by: Benjamin S. Allen <bsallen@alcf.anl.gov>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[build] Conditionalise use of -mabi=lp64 for ARM64 builds
The -mabi option was added in GCC 4.9. Test for the existence of this
option to allow for building with earlier versions of GCC.
Reported-by: Benjamin S. Allen <bsallen@alcf.anl.gov>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The UEFI specification has an implicit and demonstrably incorrect
requirement (in the Mem_IO() calling convention) that any UNDI network
device has at most one memory BAR and one I/O BAR.
Some UEFI platforms have been observed to report the existence of
non-existent additional I/O BARs, causing iPXE to select the wrong
BAR. This problem does not affect the SnpDxe driver, since that
driver will always choose the lowest numbered existent BAR of each
type.
Adjust iPXE's behaviour to match that of SnpDxe, i.e. to always select
the lowest numbered BAR(s).
Debugged-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Debugged-by: Adklei <adklei@realtek.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[smsc75xx] Expose functionality shared with LAN78xx devices
The LAN78xx datapath is essentially identical to that of the SMSC75xx.
Expose the transmit, poll, and bulk IN endpoint operations to allow
for reuse by the LAN78xx driver.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[smscusb] Allow for alternative PHY register layouts
The LAN78xx PHY interrupt source and mask registers do not match those
used by the SMSC75xx and SMSC95xx.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Since we don't enable IOMMU at all, we can then simply enable the
IOMMU support by claiming the support of VIRITO_F_IOMMU_PLATFORM.
This fixes booting failure when iommu_platform is set from qemu cli.
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[smscusb] Abstract out common SMSC USB device functionality
The smsc75xx and smsc95xx drivers include a substantial amount of
identical functionality, varying only in the base address of register
sets. Abstract out this common functionality to allow code to be
shared between the drivers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Support renegotiation with servers supporting RFC5746. This allows
for the use of per-directory client certificates.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[usb] Use non-zero language ID to retrieve strings
We currently use a zero language ID to retrieve strings such as the
ECM/NCM MAC address. This works on most hardware devices, but is
known to fail on some software emulated CDC-NCM devices.
Fix by using the first supported language ID, falling back to English
(0x0409) if any error occurs when fetching the list of supported
languages. This matches the behaviour of the Linux kernel.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
[crypto] Provide asn1_built() to construct a cursor from a builder
Our ASN.1 parsing code uses a struct asn1_cursor, while the object
construction code uses a struct asn1_builder. These structures are
identical apart from the const modifier applied to the data pointer in
struct asn1_cursor.
Provide asn1_built() to safely typecast a struct asn1_builder to a
struct asn1_cursor, allowing constructed objects to be passed to
functions expecting a struct asn1_cursor.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
For some CPUID leaves (e.g. %eax=0x00000004), the result depends on
the input value of %ecx. Allow this subfunction number to be
specified as a parameter to the cpuid() wrapper.
The subfunction number is exposed via the ${cpuid/...} settings
mechanism using the syntax
${cpuid/<subfunction>.0x40.<register>.<function>}
e.g.
${cpuid/0.0x40.0.0x0000000b}
${cpuid/1.0x40.0.0x0000000b}
to retrieve the CPU topology information.
Signed-off-by: Michael Brown <mcb30@ipxe.org>