Some vendors provide a "system MAC address" within the DSDT/SSDT, to
be used to override the MAC address for a USB docking station.
A full implementation would require an ACPI bytecode interpreter,
since at least one OEM allows the MAC address to be constructed by
executable ACPI bytecode (rather than a fixed data structure).
We instead attempt to extract a plausible-looking "_AUXMAC_#.....#"
string that appears shortly after an "AMAC" or "MACA" signature. This
should work for most implementations encountered in practice.
Debugged-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow for the DSDT/SSDT signature-scanning and value extraction code
to be reused for extracting a pass-through MAC address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit cd3de55 ("[efi] Record cached DHCPACK from loaded image's
device handle, if present") added the ability for a chainloaded UEFI
iPXE to reuse an IPv4 address and DHCP options previously obtained by
a built-in PXE stack, without needing to perform a second DHCP
request.
Extend this to also record the cached ProxyDHCPOFFER and PXEBSACK
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 a boot filename or other
options that were provided via a ProxyDHCP or PXE boot server
mechanism, rather than by standard DHCP.
Tested-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When building an EFI ROM image for which no PCI vendor/device ID is
applicable (e.g. bin-x86_64-efi/ipxe.efirom), the build process will
currently construct a command such as
./util/efirom -v -d -c bin-x86_64-efi/ipxe.efidrv \
bin-x86_64-efi/ipxe.efirom
which gets interpreted as a vendor ID of "-0xd" (i.e. 0xfff3, after
truncation to 16 bits).
Fix by using an explicit zero ID when no applicable ID exists, as is
already done when constructing BIOS ROM images.
Reported-by: Konstantin Aladyshev <aladyshev22@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The DHCP service in EC2 has been observed to occasionally stop
responding for bursts of several seconds. This can easily result in a
failed boot, since the current cloud boot script will attempt DHCP
only once.
Work around this problem by retrying DHCP in a fairly tight cycle
within the cloud boot script, and falling back to a reboot after
several failed DHCP attempts.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As of commit f1e9e2b ("[efi] Align EFI image sections by page size"),
our SectionAlignment has been increased to 4kB in order to allow for
page-level memory protection to be applied by the UEFI firmware, with
FileAlignment left at 32 bytes.
The PE specification states that the value for FileAlignment "should
be a power of 2 between 512 and 64k, inclusive", and that "if the
SectionAlignment is less than the architecture's page size, then
FileAlignment must match SectionAlignment".
Testing shows that signtool.exe will reject binaries where
FileAlignment is less than 512, unless FileAlignment is equal to
SectionAlignment. This indicates a somewhat zealous interpretation of
the word "should" in the PE specification.
Work around this interpretation by increasing FileAlignment from 32
bytes to 512 bytes, and add explanatory comments for both
FileAlignment and SectionAlignment.
Debugged-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When building the Linux userspace binaries, the external system
headers may have already defined values for the __LITTLE_ENDIAN and
__BIG_ENDIAN constants.
Fix by retaining the existing values if already defined, since the
actual values of these constants do not matter.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
RFC 3986 section 3.1 defines URI schemes as case-insensitive (though
the canonical form is always lowercase).
Use strcasecmp() rather than strcmp() to allow for case insensitivity
in URI schemes.
Requested-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The RTL8211B seems to have a bug that prevents the link from coming up
unless the MII_MMD_DATA register is cleared.
The Linux kernel driver applies this workaround (in rtl8211b_resume())
only to the specific RTL8211B PHY model, along with a matching
workaround to set bit 9 of MII_MMD_DATA when suspending the PHY.
Since we have no need to ever suspend the PHY, and since writing a
zero ought to be harmless, we just clear the register unconditionally.
Debugged-by: Nikolay Pertsev <nikolay.p@cos.flag.org>
Tested-by: Nikolay Pertsev <nikolay.p@cos.flag.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The peer discovery time has a significant impact on the overall
PeerDist download speed, since each block requires an individual
discovery attempt. In most cases, a peer that responds for block N
will turn out to also respond for block N+1.
Assume that the most recently discovered peer (for any block) probably
has a copy of the next block to be discovered, thereby allowing the
peer download attempt to begin immediately.
In the case that this assumption is incorrect, the existing error
recovery path will allow for fallback to newly discovered peers (or to
the origin server).
Suggested-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Tested-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some versions of GNU objcopy (observed with binutils 2.23.52.0.1 on
CentOS 7.0.1406) document the -D/--enable-deterministic-archives
option but fail to recognise the short form of the option.
Work around this problem by using the long form of the option.
Reported-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 040cdd0 ("[linux] Add a prefix to all symbols to avoid future
name collisions") unintentionally reintroduced an element of
non-determinism into the build ID, by omitting the -D option when
manipulating the blib.a archive.
Fix by adding the -D option to restore determinism.
Reworded-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
Most RNDIS data structures include a trailing 4-byte reserved field.
For the REMOTE_NDIS_PACKET_MSG and REMOTE_NDIS_INITIALIZE_CMPLT
structures, this is an 8-byte field instead.
iPXE currently uses incorrect structure definitions with a 4-byte
reserved field in all data structures, resulting in data payloads that
overlap the last 4 bytes of the 8-byte reserved field.
RNDIS uses explicit offsets to locate any data payloads beyond the
message header, and so liberal RNDIS parsers (such as those used in
Hyper-V and in the Linux USB Ethernet gadget driver) are still able to
parse the malformed structures.
A stricter RNDIS parser (such as that found in some older Android
builds that seem to use an out-of-tree USB Ethernet gadget driver) may
reject the malformed structures since the data payload offset is less
than the header length, causing iPXE to be unable to transmit packets.
Fix by correcting the length of the reserved fields.
Debugged-by: Martin Nield <pmn1492@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The ARM versions of the big-integer inline assembly functions include
constraints to indicate that the output value is modified by the
assembly code. These constraints are not present in the equivalent
code for the x86 versions.
As of GCC 11, this results in the compiler reporting that the output
values may be uninitialized.
Fix by including the relevant memory output constraints.
Reported-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
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>
iPXE will construct CPIO headers for images that have a non-empty
command line, thereby allowing raw images (without CPIO headers) to be
injected into a dynamically constructed initrd. This feature is
currently implemented within the BIOS-only bzImage format support.
Split out the CPIO header construction logic to allow for reuse in
other contexts such as in a UEFI build.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
DNS names are case-insensitive, and RFC 5280 (unlike RFC 3280)
mandates support for case-insensitive name comparison in X.509
certificates.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use hexadecimal values instead of macros in PCI_ROM entries so Perl
script can parse them correctly. Move PCI_ROM entries from header
file to C file. Integrate bnxt_vf_nics array into PCI_ROM entries by
introducing BNXT_FLAG_PCI_VF flag into driver_data field. Add
whitespaces in PCI_ROM entries for style consistency.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Support for the zlib and gzip archive image formats is currently
included only if the IMAGE_ARCHIVE_CMD is used to enable the
"imgextract" command.
The ability to transparently execute a single-member archive image
without using the "imgextract" command renders this unintuitive: a
user wanting to gain the ability to boot a gzip-compressed kernel
image would expect to have to enable IMAGE_GZIP rather than
IMAGE_ARCHIVE_CMD.
Reverse the inclusion logic, so that archive image formats must now be
enabled explicitly (via IMAGE_GZIP and/or IMAGE_ZLIB), with the
archive image management commands dragged in as needed if any archive
image formats are enabled. The archive image management commands may
be explicitly disabled via IMAGE_ARCHIVE_CMD if necessary.
This matches the behaviour of IBMGMT_CMD and similar options, where
the relevant commands are included only when something else already
drags in the underlying feature.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
An extracted image is wholly derived from the original archive image.
If the original archive image has been verified and marked as trusted,
then this trust logically extends to any image extracted from it.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide image_extract_exec() as a helper method to allow single-member
archive images (such as gzip compressed images) to be executed without
an explicit "imgextract" step.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid using the "rdtsc" instruction unless profiling is enabled. This
allows the non-debug build of the UNDI driver to be used on a CPU such
as a 486 that does not support the TSC.
Reported-by: Nikolai Zhubr <n-a-zhubr@yandex.ru>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The decompressor uses the i486 "bswap" instruction, but does not
require any instructions that exist only on i586 or above. Update the
".arch" directive to reflect the requirements of the code as
implemented.
Reported-by: Martin Habets <habetsm.xilinx@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add the concept of extracting an image from an archive (which could be
a single-file archive such as a gzip-compressed file), along with an
"imgextract" command to expose this functionality to scripts.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
Commit 79c0173 ("[build] Create util/genfsimg for building
filesystem-based images") introduced the new genfsimg, which lacks the
-l option when building ISO files. This option is required to build
level 2 (long plain) ISO9660 filenames, which are required when using
the .lkrn extensions on older versions of ISOLINUX.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The use of jumbo frames for the Xen netfront virtual NIC requires the
use of scatter-gather ("feature-sg"), with the receive descriptor ring
becoming a list of page-sized buffers and the backend using as many
page buffers as required for each packet.
Since iPXE's abstraction of an I/O buffer does not include any sort of
scatter-gather list, this requires an extra allocation and copy on the
receive datapath for any packet that spans more than a single page.
This support is required in order to successfully boot an AWS EC2
virtual machine (with non-enhanced networking) via iSCSI if jumbo
frames are enabled, since the netback driver used in EC2 seems not to
allow "feature-sg" to be renegotiated once the Linux kernel driver
takes over.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The INT 13 extensions provide a mechanism for accessing disks using
linear (LBA) rather than C/H/S addressing. SAN protocols such as
iSCSI invariably support only linear addresses and so iPXE currently
provides LBA access to all SAN disks (with autodetection and emulation
of an appropriate geometry for C/H/S accesses).
Most BIOSes will not report support for INT 13 extensions for floppy
disk drives, and some operating systems may be confused by a floppy
drive that claims such support.
Minimise surprise by reporting the existence of support for INT 13
extensions only for non-floppy drive numbers. Continue to provide
support for all drive numbers, to avoid breaking operating systems
that may unconditionally use the INT 13 extensions without first
checking for support.
Reported-by: Valdo Toost <vtoost@hot.ee>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When CONSOLE_SYSLOG is used, a DBG() from within a network device
driver may cause its transmit() or poll() methods to be unexpectedly
re-entered. Since these methods are not intended to be re-entrant,
this can lead to undefined behaviour.
Add an explicit re-entrancy guard to both methods. Note that this
must operate at a per-netdevice level, since there are legitimate
circumstances under which the netdev_tx() or netdev_poll() functions
may be re-entered (e.g. when using VLAN devices).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
There is no method for obtaining the number of PCI buses when using
PCIAPI_DIRECT, and we therefore currently scan all possible bus
numbers. This can cause a several-second startup delay in some
virtualised environments, since PCI configuration space access will
necessarily require the involvement of the hypervisor.
Ameliorate this situation by defaulting to scanning only a single bus,
and expanding the number of PCI buses to accommodate any subordinate
buses that are detected during enumeration.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Adding this missing identifier allows the X557-AT2 chipset seen on (at
least) Super Micro A2SDI-H-TF motherboards to function with iPXE.
Signed-off-by: Tyler J. Stachecki <stachecki.tyler@gmail.com>
After a PE image is fully loaded and relocated, the loader code may
opt to zero discardable sections for security reasons. This includes
relocation and debug information, as both contain hints about specific
locations within the binary. Mark both generated sections as
discardable, which follows the PE specification.
Signed-off-by: Marvin Häuser <mhaeuser@posteo.de>
For optimal memory permission management, PE sections need to be
aligned by the platform's minimum page size. Currently, the PE
section alignment is fixed to 32 bytes, which is below the typical 4kB
page size. Align all sections to 4kB and adjust ELF to PE image
conversion accordingly.
Signed-off-by: Marvin Häuser <mhaeuser@posteo.de>
As per https://github.com/ipxe/ipxe/pull/313#issuecomment-816018398,
these sections are not required for EFI execution. Discard them to
avoid implementation-defined alignment malforming binaries.
Signed-off-by: Marvin Häuser <mhaeuser@posteo.de>
Handle a DHCPNAK by returning to the discovery state to allow iPXE to
attempt to obtain a replacement IPv4 address.
Reuse the existing logic for deferring discovery when the link is
blocked: this avoids hammering a misconfigured DHCP server with a
non-stop stream of requests and allows the DHCP process to eventually
time out and fail.
Originally-implemented-by: Blake Rouse <blake.rouse@canonical.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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 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>
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>
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>
The DNS server list is currently printed as a debug message whenever
settings are applied. This can result in some very noisy debug logs
when a script makes extensive use of settings.
Move the DNS server list debug messages to DBGLVL_EXTRA.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow arbitrary settings to be specified on the Linux command line.
For example:
./bin-x86_64-linux/slirp.linux \
--net slirp,testserver=qa-test.ipxe.org
This can be useful when using the Linux userspace build to test
embedded scripts, since it allows arbitrary parameters to be passed
directly on the command line.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
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>
The "used" attribute can be applied only to functions or variables,
which prevents the use of __asmcall as a type attribute.
Fix by removing "used" from the definition of __asmcall for i386 and
x86_64 architectures, and adding explicit __used annotations where
necessary.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
The result from acpi_find_rsdt() is used only for the debug message.
Simplify the debug message and remove the otherwise redundant call to
acpi_find_rsdt().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
Allow for the possibility of linking to platform libraries for the
Linux userspace build by adding an iPXE-specific symbol prefix.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Recent versions of the GNU assembler (observed with GNU as 2.35 on
Fedora 33) will produce a warning message
Warning: no instruction mnemonic suffix given and no register
operands; using default for `bts'
The operand size affects only the potential range for the bit number.
Since we pass the bit number as an unsigned int, it is already
constrained to 32 bits for both i386 and x86_64.
Silence the assembler warning by specifying an explicit 32-bit operand
size (and thereby matching the choice that the assembler would
otherwise make automatically).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use the reference implementation of the EFI compression algorithm
(taken from the EDK2 codebase, with minor bugfixes to allow
compilation with -Werror) to compress EFI ROM images.
Inspired-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Assume that preservation of the %xmm registers is unnecessary during
installation of iPXE into memory, since this is an operation that by
its nature substantially disrupts large portions of the system anyway
(such as the E820 memory map). This assumption allows us to utilise
the existing CPUID code to check that FXSAVE/FXRSTOR are supported.
Test for support during the call to init_librm and store the flag for
use during subsequent calls to virt_call.
Reduce the scope of TIVOLI_VMM_WORKAROUND to affecting only the call
to check_fxsr(), to reduce #ifdef pollution in the remaining code.
Debugged-by: Johannes Heimansberg <git@jhe.dedyn.io>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The __asmcall declaration has no effect on a void function with no
parameters, but should be included for completeness since the function
is called directly from assembly code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide a generic raw image prefix, which assumes that the iPXE image
has been loaded in its entirety on a paragraph boundary.
The resulting .raw image can be loaded via RPL using an rpld.conf file
such as:
HOST {
ethernet = 00:00:00:00:00:00/6;
FILE {
path="ipxe.raw";
load=0x2000;
};
execute=0x2000;
};
Debugged-by: Johannes Heimansberg <git@jhe.dedyn.io>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A zero-length initrd file will currently cause an endless loop during
reshuffling as the empty image is repeatedly swapped with itself.
Fix by terminating the inner loop before considering an image as a
candidate to be swapped with itself.
Reported-by: Pico Mitchell <pico@randomapplications.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Most EFI firmware builds (including those found on ARM64 instances in
AWS EC2) will already send console output to the serial port.
Do not enable direct serial console output in EFI builds using
CONFIG=cloud.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
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>
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>
Split out the portions of cachedhcp.c that can be shared between BIOS
and UEFI (both of which can provide a buffer containing a previously
obtained DHCP packet, and neither of which provide a means to
determine the length of this DHCP packet).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The GCC11 compiler pointed out something that apparently no previous
compiler noticed: in ath5k_eeprom_pread_turbo_modes, local variable
val is used uninitialized. From what I can see, the code is just
missing an initial AR5K_EEPROM_READ. Add it right before the switch
statement.
Signed-off-by: Bruce Rogers <brogers@suse.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some versions of GNU ld (observed with binutils 2.36 on Arch Linux)
introduce a .note.gnu.property section marked as loadable at a high
address and with non-empty contents. This adds approximately 128MB of
garbage to the BIOS .usb disk images.
Fix by using a custom linker script for the prefix-only binaries such
as the USB disk partition table and MBR, in order to allow unwanted
sections to be explicitly discarded.
Reported-by: Christian Hesse <mail@eworm.de>
Tested-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The version of SeaBIOS found on some AWS EC2 instances (observed with
t3a.nano in eu-west-1) has no support for the INT 1A PCI BIOS calls.
Bring config/ioapi.h into the named-configuration set of headers, and
specify the use of PCIAPI_DIRECT for CONFIG=cloud, to work around the
missing PCI BIOS support.
Switching to a different named configuration will now unfortunately
cause an almost complete rebuild of iPXE. As described in commit
c801cb2 ("[build] Allow for named configurations at build time"), this
is the reason why config/ioapi.h was not originally in the
named-configuration set of header files.
This rebuild cost is acceptable given that build times are
substantially faster now than seven years ago, and that very few
people are likely to be switching named configurations on a regular
basis.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Linux and FreeBSD drivers for the (totally undocumented) ENA
adapters use a two-phase reset mechanism: first set ENA_CTRL.RESET and
wait for this to be reflected in ENA_STAT.RESET, then clear
ENA_CTRL.RESET and again wait for it to be reflected in
ENA_STAT.RESET.
The iPXE driver currently assumes a self-clearing reset mechanism,
which appeared to work at the time that the driver was created but
seems no longer to function, at least on the t3.nano and t3a.nano
instance types found in eu-west-1.
Switch to a simplified version of the two-phase reset mechanism as
used by Linux and FreeBSD.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The semantics of the assembler's .align directive vary by CPU
architecture. For the ARM builds, it specifies a power of two rather
than a number of bytes. This currently leads to the .einfo entries
(which do not appear in the final binary) having an alignment of 256
bytes for the ARM builds.
Fix by switching to the GNU-specific directive .balign, which is
consistent across architectures
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Support for building with the Intel C compiler (icc) was added in 2009
in the expectation that UEFI support would eventually involve
compiling iPXE to EFI Byte Code.
EFI Byte Code has never found any widespread use: no widely available
compilers can emit it, Microsoft refuses to sign EFI Byte Code
binaries for UEFI Secure Boot, and I have personally never encountered
any examples of EFI Byte Code in the wild.
The support for using the Intel C compiler has not been tested in over
a decade, and would almost certainly require modification to work with
current releases of the compiler.
Simplify the build process by removing this old legacy code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As of commit 7c3d186 ("[build] Check that mkisofs equivalent supports
the required options"), we may refuse to use a mkisofs equivalent if
it does not support the options required to produce the requested
output file.
This can result in confusing error messages since the user is unaware
of the reason for which the installed mkisofs or genisoimage has been
rejected.
Fix by explicitly reporting the reason why each possible mkisofs
equivalent could not be used.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some patched versions of gcc (observed with gcc 9.3.0 on Ubuntu 20.04)
enable -fcf-protection=full by default. This breaks code that is not
explicitly written to expect the use of this flag. The breakage
occurs only at runtime if the affected code (such as setjmp()) happens
to execute, and is therefore a particularly pernicious class of bug to
be introduced into working code by a broken compiler.
Work around these broken patched versions of gcc by detecting support
for -fcf-protection and explicitly setting -fcf-protection=none if
found.
If any Ubuntu maintainers are listening: PLEASE STOP DOING THIS. It's
extremely unhelpful to have to keep working around breakages that you
introduce by modifying the compiler's default behaviour. Do what Red
Hat does instead: set your preferred CFLAGS within the package build
system rather than by patching the compiler to behave in violation of
its own documentation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Several distributions include versions of gcc that are patched to
create position-independent executables by default. These have caused
multiple problems over the years: see e.g. commits fe61f6d ("[build]
Fix compilation when gcc is patched to default to -fPIE -Wl,-pie"),
5de1346 ("[build] Apply the "-fno-PIE -nopie" workaround only to i386
builds"), 7c395b0 ("[build] Use -no-pie on newer versions of gcc"),
and decee20 ("[build] Disable position-independent code for ARM64 EFI
builds").
The build system currently attempts to work around these mildly broken
patched versions of gcc for the i386 and arm64 architectures. This
misses the relatively obscure bin-x86_64-pcbios build platform, which
turns out to also require the same workaround.
Attempt to preempt the next such required workaround by moving the
existing i386 version to apply to all platforms and all architectures,
unless -fpie has been requested explicitly by another Makefile (as is
done by arch/x86_64/Makefile.efi).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The function trace recorder build logic defaults to making "clean" a
dependency of the first build in a clean checkout. This is redundant
and causes problems if the build process spins up multiple make
invocations to handle multiple build architectures.
Fix by replacing with logic based on the known-working patterns used
for the ASSERT and PROFILE build parameters.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
After a ton of tedious work, I am pleased to finally introduce full
support for ConnectX-3 cards in iPXE!
The work has been done by finding all publicly available versions of
the Mellanox Flexboot sources, cleaning them up, synthesizing a git
history from them, cleaning out non-significant changes, and
correlating with the iPXE upstream git history.
After this, a proof-of-concept diff was produced, that allowed iPXE to
be compiled with rudimentary ConnectX-3 support. This diff was over
10k lines, and contained many changes that were not part of the core
driver.
Special thanks to Michael Brown <mcb30@ipxe.org> for answering my
barrage of questions, and helping brainstorm the development along the
way.
Signed-off-by: Christian Iversen <ci@iversenit.dk>
Some network devices can take a substantial time to close and reopen.
Avoid closing the device from which we are about to attempt booting,
in case it happens to be already open.
Suggested-by: Christian Iversen <ci@iversenit.dk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The CQE length field will not be valid for a completion in error.
Avoid parsing the length field and just call the completion handler
directly.
In debug builds, also dump the queue pair context to allow for
inspection of the error.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Check for reset completion by waiting for the device to respond to PCI
configuration cycles, as documented in the Programmer's Reference
Manual. On the original ConnectX HCA, this reduces the time spent on
reset from 1000ms down to 1ms.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When auto-detecting the initial port type, the Hermon driver will spam
the debug output without hesitation. Add a short delay in each
iteration to fix this.
Signed-off-by: Christian Iversen <ci@iversenit.dk>
Inspired by Flexboot, the function hermon_event_port_mgmnt_change() is
added to handle the HERMON_EV_PORT_MGMNT_CHANGE event type, which
updates the Infiniband subsystem.
Signed-off-by: Christian Iversen <ci@iversenit.dk>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hermon Ethernet work queues have more RX than TX entries, unlike most
other drivers. This is possibly the source of some stochastic
deadlocks previously experienced with this driver.
Update the sizes to be in line with other drivers, and make them
slightly larger for better performance. These new queue sizes have
been found to work well with ConnectX-3 hardware.
Signed-off-by: Christian Iversen <ci@iversenit.dk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The programming documentation states that the reset magic value is
"0x00000001 (Big Endian)", and the current code matches this by using
the value 0x01000000 for the implicitly little-endian writel().
Inspection of the FlexBoot source code reveals an exciting variety of
reset values, some suggestive of confusion around endianness.
Experimentation suggests that the value 0x01000001 works reliably
across a wide range of hardware.
Debugged-by: Christian Iversen <ci@iversenit.dk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some older versions of the hardware (and/or firmware) do not report an
event when an Infiniband link reaches the INIT state. The driver
works around this missing event by calling ib_smc_update() on each
event queue poll while the link is in the DOWN state.
Commit 6cb12ee ("[hermon] Increase polling rate for command
completions") addressed this by speeding up the time taken to issue
each command invoked by ib_smc_update(). Experimentation shows that
the impact is still significant: for example, in a situation where an
unplugged port is opened, the throughput on the other port can be
reduced by over 99%.
Fix by throttling the rate at which link polling is attempted.
Debugged-by: Christian Iversen <ci@iversenit.dk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The version of awk used in FreeBSD seems to be incapable of formatting
unsigned 32-bit integers above 0x80000000 and will silently render any
such value as 0x80000000. For example:
echo 3735928559 | awk '{printf "0x%08x", $1}'
will produce 0x80000000 instead of the correct 0xdeadbeef.
This results in an approximately 50% chance of a build ID collision
when building on FreeBSD.
Work around this problem by passing the decimal value directly in the
ld --defsym argument value.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add a few more ABSOLUTE() expressions to convince the FreeBSD linker
that already-absolute symbols are, in fact, absolute.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The elftoolchain version of objcopy (as used in FreeBSD) seems to be
unusable for generating a raw binary file, since it will apparently
ignore the load memory addresses specified for each section in the
input file.
The binutils version of objcopy may be used on FreeBSD by specifying
OBJCOPY=/usr/local/bin/objcopy
Detect an attempt to use the unusable elftoolchain version of objcopy
and report it as an error.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some versions of objcopy will spuriously complain when asked to
extract the .zinfo section since doing so will nominally alter the
load addresses of the (non-loadable) .bss.* sections.
Avoid these warnings by placing the .zinfo section at the very end of
the load memory address space.
Allocate non-overlapping load memory addresses for the (non-loadable)
.bss.* sections, in the hope of avoiding spurious warnings about
overlapping load addresses.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Calculate the build ID as a checksum over the input files. Since the
input files include $(BIN)/version.%.o which itself includes the build
target name (from which TGT_LD_FLAGS is calculated), this should be
sufficient to meet the requirement that the build ID be unique for
each $(BIN)/%.tmp even within the same build run.
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When using $(shell), make will first invoke BUILD_ID_CMD and then have
the value defined when calling $(LD). This means we get to see the
_build_id when building with make V=1. Previously the build_id was
figured out as a subshell command run during the recipe execution
without being able to see the build_id itself.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Directories may be left behind by failed filesystem image builds, and
will not currently be successfully removed by a "make clean".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The elf.h on FreeBSD defines ELF_R_TYPE and ELF_R_SYM (based on the
host platform) and omits some but not all of the AArch64 relocation
types.
Fix by undefining ELF_R_TYPE and ELF_R_SYM in favour of our own
definitions, and by placing each potentially missing relocation type
within an individual #ifdef guard.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The -boot-info-table option to mkisofs will cause it to overwrite a
portion of the local copy of isolinux.bin. Ensure that this file is
writable.
Originally-implemented-by: Nikolai Lifanov <lifanov@mail.lifanov.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Make the contents of $(BLIB) deterministic to allow it to be
subsequently used for calculating a build ID.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This change is ported from Flexboot sources. When stopping a Hermon
device, perform hermon_unmap_mpt() which runs HERMON_HCR_HW2SW_MPT to
bring the Memory Protection Table (MPT) back to software control.
Signed-off-by: Christian Iversen <ci@iversenit.dk>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The eIPoIB local Ethernet MAC is currently constructed from the port
GUID. Given a base GUID/MAC value of N, Mellanox seems to populate:
Node GUID: N + 0
Port 1 GUID: N + 1
Port 2 GUID: N + 2
and
Port 1 MAC: N + 0
Port 2 MAC: N + 1
This causes a duplicate local MAC address when port 1 is configured as
Infiniband and port 2 as Ethernet, since both will derive their MAC
address as (N + 1).
Fix by using the port's Ethernet MAC as the eIPoIB local EMAC. This
is a behavioural change that could potentially break configurations
that rely on the local EMAC value, such as a DHCP server relying on
the chaddr field for DHCP reservations.
Signed-off-by: Christian Iversen <ci@iversenit.dk>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some older versions of the hardware (and/or firmware) do not report an
event when an Infiniband link reaches the INIT state. The driver
works around this missing event by calling ib_smc_update() on each
event queue poll while the link is in the DOWN state. This results in
a very large number of commands being issued while any open Infiniband
link is in the DOWN state (e.g. unplugged), to the point that the 1ms
delay from waiting for each command to complete will noticeably affect
responsiveness.
Fix by decreasing the command completion polling delay from 1ms to
10us.
Signed-off-by: Christian Iversen <ci@iversenit.dk>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add hermon_dump_eqctx() for dumping the event queue context and
hermon_dump_eqes() for dumping any unconsumed event queue entries.
Originally-implemented-by: Christian Iversen <ci@iversenit.dk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some commands (particularly in relation to device initialization) can
occasionally take longer than 2 seconds, and the Mellanox documentation
recommends a 10 second timeout.
Signed-off-by: Christian Iversen <ci@iversenit.dk>
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>
iPXE when used as a NIC option ROM can sometimes be reloaded by the
UEFI/BIOS and any pre-initialised memory will remain loaded. When the
imgtrust command is run it sets `require_trusted_images'. Upon
reloading, iPXE tries to load the first embedded image but fails as it
is not marked trusted.
Setting this flag ensures that imgtrust with the first embedded script
is reentrant.
Signed-off-by: Joe Groocock <jgroocock@cloudflare.com>
Require drivers to report the total number of Infiniband ports. This
is necessary to report the correct number of ports on devices with
dynamic port types.
For example, dual-port Mellanox cards configured for (eth, ib) would
be rejected by the subnet manager, because they report using "port 2,
out of 1".
Signed-off-by: Christian Iversen <ci@iversenit.dk>
This is useful on devices that perform auto-detection for ports.
Example output:
iPXE> ifstat
net0: 00:11:22:33:44:55 using mt4099 on 0000:00:03.0 (Ethernet) [open]
[Link:down, TX:0 TXE:0 RX:0 RXE:0]
[Link status: Unknown (http://ipxe.org/1a086101)]
net1: 00:11:22:33:44:56 using mt4099 on 0000:00:03.0 (IPoIB) [open]
[Link:down, TX:0 TXE:0 RX:0 RXE:0]
[Link status: Initialising (http://ipxe.org/1a136101)]
Signed-off-by: Christian Iversen <ci@iversenit.dk>
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>
Consolidate the remaining logic common to initrd_init() and imgmem()
into a shared image_memory() function.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The "-e" option required for creating EFI boot images is supported
only by widely used patched versions of genisoimage.
Check that the required options are supported when selecting a mkisofs
equivalent, thereby allowing a fallback to the use of xorrisofs when
building a UEFI ISO image on a system with an unpatched version of
genisoimage.
Continue to prefer the use of genisoimage over xorrisofs, since there
is apparently no way to inhibit the irritatingly useless startup
banner message printed by xorrisofs even when the "-quiet" option is
specified.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide some visibility into the turnaround times on both client and
server sides as perceived by iPXE, to assist in debugging inexplicably
slow TFTP transfers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide the "imgmem" command to create an image from an existing block
of memory, for debugging purposes only.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
For FAT filesystem images larger than a 1.44MB floppy disk, round up
the image size to a whole number of 504kB cylinders before formatting.
This avoids losing up to a cylinder's worth of expected space in the
filesystem image.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow generated filesystem images to be accessed using the file:// URI
syntax by setting a defined volume name. This allows a script placed
on the same filesystem image to be accessed using e.g.
chain file://iPXE/script.ipxe
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Extract the PE header offset from the MZ header rather than assuming a
fixed offset as used in the binaries created by the iPXE build system.
This allows genfsimg to be used to create bootable filesystem images
from third party UEFI binaries such as the UEFI shell.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
With the default timeouts for Cisco MAC Authentication Bypass, the
link will remain blocked for around 90 seconds (plus a likely
subsequent delay for STP).
Extend the maximum number of DHCP discovery deferrals to allow for up
to three minutes of waiting for a link to become unblocked.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A switch port using 802.1x authentication will send EAP
Request-Identity packets once the physical link is up, and will not be
forwarding packets until the port identity has been established.
We do not currently support 802.1x authentication. However, a
reasonably common configuration involves using a preset list of
permitted MAC addresses, with the "authentication" taking place
between the switch and a RADIUS server. In this configuration, the
end device does not need to perform any authentication step, but does
need to be prepared for the switch port to fail to forward packets for
a substantial time after physical link-up. This exactly matches the
"blocked link" semantics already used when detecting a non-forwarding
switch port via LACP or STP.
Treat a received EAP Request-Identity as indicating a blocked link.
Unlike LACP or STP, there is no way to determine the expected time
until the next EAP packet and so we must choose a fixed timeout.
Erroneously assuming that the link is blocked is relatively harmless
since we will still attempt to transmit and receive data even over a
link that is marked as blocked, and so the net effect is merely to
prolong DHCP attempts. In contrast, erroneously assuming that the
link is unblocked will potentially cause DHCP to time out and give up,
resulting in a failed boot.
The default EAP Request-Identity interval in Cisco switches (where
this is most likely to be encountered in practice) is 30 seconds, so
choose 45 seconds as a timeout that is likely to avoid gaps during
which we falsely assume that the link is unblocked.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Replace the GPL2+-only EAPoL code (currently used only for WPA) with
new code licensed under GPL2+-or-UBDL.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Continue to transmit DHCPDISCOVER while waiting for a blocked link, in
order to support mechanisms such as Cisco MAC Authentication Bypass
that require repeated transmission attempts in order to trigger the
action that will result in the link becoming unblocked.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add support for xorrisofs, a GNU mkisofs equivalent that is available
in most distro repositories.
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some versions of gcc (observed with gcc 9.3.0 on NixOS Linux) produce
a spurious warning about an out-of-bounds array access for the
isa_extra_probe_addrs[] array.
Work around this compiler bug by redefining the array index as a
signed long, which seems to somehow avoid this spurious warning.
Debugged-by: Manuel Mendez <mmendez534@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Generalise util/geniso, util/gensdsk, and util/genefidsk to create a
single script util/genfsimg that can be used to build either FAT
filesystem images or ISO images.
Extend the functionality to allow for building multi-architecture UEFI
bootable ISO images and combined BIOS+UEFI images.
For example:
./util/genfsimg -o combined.iso \
bin-x86_64-efi/ipxe.efi \
bin-arm64-efi/ipxe.efi \
bin/ipxe.lkrn
would generate a hybrid image that could be used as a CDROM (or hard
disk or USB key) on legacy BIOS, x86_64 UEFI, or ARM64 UEFI.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
Ensure that any command failure messages are followed up with an error
message indicating what the failed command was attempting to perform.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The xHCI driver can handle only a single command TRB in progress at
any one time. Immediately fail any attempts to issue concurrent
commands (which should not occur in normal operation).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
Email from solarflare.com will stop working, so update those. Remove
email for Shradha Shah, as she is not involved with this any more.
Update copyright notices for files touched.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We surface this debugging information in cases where a cert actually
lacks an issuer, but also in cases where it *has* an issuer, but we
cannot trust it (e.g. due to issues in establishing a trust chain).
Signed-off-by: Josh McSavaney <me@mcsau.cc>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
USB tethering via an iPhone is unreasonably complicated due to the
requirement to perform a pairing operation that involves establishing
a TLS session over a completely unrelated USB function that speaks a
protocol that is almost, but not quite, entirely unlike TCP.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Record the root of trust used at the point that a certificate is
validated, redefine validation as checking a certificate against a
specific root of trust, and pass an explicit root of trust when
creating a TLS connection.
This allows a custom TLS connection to be used with a custom root of
trust, without causing any validated certificates to be treated as
valid for normal purposes.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
OCSP currently calls x509_validate() with an empty root certificate
list, on the basis that the OCSP signer certificate (if existent) must
be signed directly by the issuer certificate.
Using an empty root certificate list is not required to achieve this
goal, since x509_validate() already accepts an explicit issuer
certificate parameter. The explicit empty root certificate list
merely prevents the signer certificate from being evaluated as a
potential trusted root certificate.
Remove the dummy OCSP root certificate list and use the default root
certificate list when calling x509_validate().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
There is nothing OID-specific about the ASN1_OID_CURSOR macro. Rename
to allow it to be used for constructing ASN.1 cursors with arbitrary
contents.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use the existing certificate store to automatically append any
available issuing certificates to the selected client certificate.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Restructure the use of add_tls() to insert a TLS filter onto an
existing interface. This allows for the possibility of using
add_tls() to start TLS on an existing connection (as used in several
protocols which will negotiate the choice to use TLS before the
ClientHello is sent).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Generalise the filter interface insertion logic from block_translate()
and expose as intf_insert(), allowing a filter interface to be
inserted on any existing interface.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
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>
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>
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>
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>
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>
Unlike netdev_rx_err(), there is no valid circumstance under which
netdev_rx() may be called with a null I/O buffer, since a call to
netdev_rx() represents the successful reception of a packet. Fix the
code comment to reflect this.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
netdev_tx_err() may be called with a null I/O buffer (e.g. to record a
transmit error with no associated buffer). Avoid a potential null
pointer dereference in the DMA unmapping code path.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
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>
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>
For the physical function driver, the transmit queue needs to be
configured to be associated with the relevant physical function
number. This is currently obtained from the bus:dev.fn address of the
underlying PCI device.
In the case of a virtual machine using the physical function via PCI
passthrough, the PCI bus:dev.fn address within the virtual machine is
unrelated to the real physical function number. Such a function will
typically be presented to the virtual machine as a single-function
device. The function number extracted from the PCI bus:dev.fn address
will therefore always be zero.
Fix by reading from the Function Requester ID Information Register,
which always returns the real PCI bus:dev.fn address as used by the
physical host.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The datasheet is fairly incomprehensible in terms of identifying the
appropriate MAC address for use by the physical function driver.
Choose to read the MAC address from PRTPM_SAH and PRTPM_SAL, which at
least matches the MAC address as selected by the Linux i40e driver.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
Physical addresses in debug messages are more meaningful from an
end-user perspective than potentially IOMMU-mapped I/O virtual
addresses, and have the advantage of being calculable without access
to the original DMA mapping entry (e.g. when displaying an address for
a single failed completion within a descriptor ring).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
For a software UNDI, the addresses in PXE_CPB_TRANSMIT.FrameAddr and
PXE_CPB_RECEIVE.BufferAddr are host addresses, not bus addresses.
Remove the spurious (and no-op) use of virt_to_bus() and replace with
a cast via intptr_t.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The UEFI specification defines PXE_CPB_TRANSMIT.DataLen as excluding
the length of the media header. iPXE currently fills in DataLen as
the whole frame length (including the media header), along with
placing the media header length separately in MediaheaderLen. On some
UNDI implementations (observed using a VMware ESXi 7.0b virtual
machine), this causes transmitted packets to include 14 bytes of
trailing garbage.
Match the behaviour of the EDK2 SnpDxe driver, which fills in DataLen
as the whole frame length (including the media header) and leaves
MediaheaderLen as zero. This behaviour also violates the UEFI
specification, but is likely to work in practice since EDK2 is the
reference implementation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently assumes that DMA-capable devices can directly address
physical memory using host addresses. This assumption fails when
using an IOMMU.
Define an internal DMA API with two implementations: a "flat"
implementation for use in legacy BIOS or other environments in which
flat physical addressing is guaranteed to be used and all allocated
physical addresses are guaranteed to be within a 32-bit address space,
and an "operations-based" implementation for use in UEFI or other
environments in which DMA mapping may require bus-specific handling.
The purpose of the fully inlined "flat" implementation is to allow the
trivial identity DMA mappings to be optimised out at build time,
thereby avoiding an increase in code size for legacy BIOS builds.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
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>
Provide opened EFI PCI devices with access to the underlying
EFI_PCI_IO_PROTOCOL instance, in order to facilitate the future use of
the DMA mapping methods within the fast data path.
Do not require the use of this stored EFI_PCI_IO_PROTOCOL instance for
memory-mapped I/O (since the entire point of memory-mapped I/O as a
concept is to avoid this kind of unnecessary complexity) or for
slow-path PCI configuration space accesses (since these may be
required for access to PCI bus:dev.fn addresses that do not correspond
to a device bound via our driver binding protocol instance).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The legacy transmit descriptor index is not reset by anything short of
a full device reset. This can cause the legacy transmit ring to stall
after closing and reopening the device, since the hardware and
software indices will be out of sync.
Fix by performing a reset after closing the interface. Do this only
if operating in legacy mode, since in C+ mode the reset is not
required and would undesirably clear additional state (such as the C+
command register itself).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some UEFI systems (observed with a Supermicro X11SPG-TF motherboard)
seem to fail to provide a valid ACPI address space descriptor for the
MMIO address space associated with a PCI root bridge.
If no valid descriptor can be found, fall back to assuming that the
MMIO address space is identity mapped, thereby matching the behaviour
prior to commit 27e886c ("[efi] Use address offset as reported by
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL").
Debugged-by: Tore Anderson <tore@fud.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 87e39a9c9 ("[efi] Split efi_usb_path() out to a separate
function") unintentionally introduced an undefined symbol reference
from efi_path.o to usb_depth(), causing the USB subsystem to become a
dependency of all EFI builds.
Fix by converting usb_depth() to a static inline function.
Reported-by: Pico Mitchell <pico@randomapplications.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The UEFI specification allows uninstallation of a protocol interface
to fail. There is no sensible way for code to react to this, since
uninstallation is likely to be taking place on a code path that cannot
itself fail (e.g. a code path that is itself a failure path).
Where the protocol structure exists within a dynamically allocated
block of memory, this leads to possible use-after-free bugs. Work
around this unfortunate design choice by nullifying the protocol
(i.e. overwriting the method pointers with no-ops) and leaking the
memory containing the protocol structure.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use the device path constructed via efi_describe() for the installed
EFI_BLOCK_IO_PROTOCOL device handle.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The UEFI specification provides a partial definition of an Infiniband
device path structure. Use this structure to construct what may be a
plausible path containing at least some of the information required to
identify an SRP target device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The ACPI table contents are typically large and are likely to cause
any preceding error messages to scroll off-screen.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
There is no standard defined for AoE device paths in the UEFI
specification, and it seems unlikely that any standard will be adopted
in future.
Choose to construct an AoE device path using a concatenation of the
network device path and a SATA device path, treating the AoE major and
minor numbers as the HBA port number and port multiplier port number
respectively.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide efi_netdev_path() as a standalone function, to allow for reuse
when constructing child device paths.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow an interface operation to be declared as unused. This will
perform full type-checking and compilation of the implementing method,
without including any code in the resulting object (other than a NULL
entry in the interface operations table).
The intention is to provide a relatively clean way for interface
operation methods to be omitted in builds for which the operation is
not required (such as an operation to describe an object using an EFI
device path, which would not be required in a non-EFI build).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Now that IPv6 is enabled by default for UEFI builds, it is important
that iPXE does not delay unnecessarily in the (still relatively
common) case of a network that lacks IPv6 routers.
Apply the timeout values used for neighbour discovery to the router
discovery process.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
IPv6 PXE was included in the UEFI specification over eight years ago,
specifically in version 2.3 (Errata D).
http://www.uefi.org/sites/default/files/resources/UEFI_Spec_2_3_D.pdf
When iPXE is being chainloaded from a UEFI firmware performing a PXE
boot in an IPv6 network, it is essential that iPXE supports IPv6 as
well.
I understand that the reason for NET_PROTO_IPV6 being disabled by
default (in src/config/general.h) is that it would cause certain
space-constrained build targets to become too large. However, this
should not be an issue for EFI builds.
It is also worth noting that RFC 6540 makes a clear recommendation
that IPv6 support should not be considered optional.
https://tools.ietf.org/html/rfc6540
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Tore Anderson <tore@fud.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The LACP responder reuses the received I/O buffer to construct the
response LACP (or marker) packet. Any received padding will therefore
be unintentionally included within the response.
Truncate the received I/O buffer to the expected length (which is
already defined in a way to allow for future protocol expansion)
before reusing it to construct the response.
Reported-by: Tore Anderson <tore@fud.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some external drivers (observed with the UEFI NII driver provided by
an HPE-branded Mellanox ConnectX-3 Pro) seem to cause LACP packets
transmitted by iPXE to be looped back as received packets. Since
iPXE's trivial LACP responder will send one response per received
packet, this results in an immediate LACP packet storm.
Detect looped back LACP packets (based on the received LACP actor MAC
address), and refuse to respond to such packets.
Reported-by: Tore Anderson <tore@fud.no>
Tested-by: Tore Anderson <tore@fud.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When iPXE is downloading a file from an EFI_FILE_PROTOCOL instance
backed by an EFI_BLOCK_IO_PROTOCOL instance provided by the same iPXE
binary (e.g. via a hooked SAN device), then it is possible for step()
to be invoked as a result of the calls into the EFI_BLOCK_IO_PROTOCOL
methods. This can potentially result in efi_local_step() being run
prematurely, before the file has been opened and before the parent
interface has been attached.
Fix by deferring starting the download process until immediately prior
to returning from efi_local_open().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some UEFI BIOSes (observed with at least the Insyde UEFI BIOS on a
Microsoft Surface Go) provide a very broken version of the
UsbMassStorageDxe driver that is incapable of binding to the standard
EFI_USB_IO_PROTOCOL instances and instead relies on an undocumented
proprietary protocol (with GUID c965c76a-d71e-4e66-ab06-c6230d528425)
installed by the platform's custom version of UsbCoreDxe.
The upshot is that USB mass storage devices become inaccessible once
iPXE's native USB host controller drivers are loaded.
One possible workaround is to load a known working version of
UsbMassStorageDxe (e.g. from the EDK2 tree): this driver will
correctly bind to the standard EFI_USB_IO_PROTOCOL instances exposed
by iPXE. This workaround is ugly in practice, since it involves
embedding UsbMassStorageDxe.efi into the iPXE binary and including an
embedded script to perform the required "chain UsbMassStorageDxe.efi".
Provide a native USB mass storage driver for iPXE, allowing USB mass
storage devices to be exposed as iPXE SAN devices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE will often have multiple drivers available for a USB device. For
example: some USB network devices will support both RNDIS and CDC-ECM,
and any device may be consumed by the fallback "usbio" driver under
UEFI in order to expose an EFI_USB_IO_PROTOCOL instance.
The driver scoring mechanism is used to select a device configuration
based on the availability of drivers for the interfaces exposed in
each configuration.
For the case of RNDIS versus CDC-ECM, this mechanism will always
produce the correct result since RNDIS and CDC-ECM will not exist
within the same configuration and so each configuration will receive a
score based on the relevant driver.
This guarantee does not hold for the "usbio" driver, which will match
against any device. It is a surprising coincidence that the "usbio"
driver seems to usually end up at the tail end of the USB drivers
list, thereby resulting in the expected behaviour.
Guarantee the expected behaviour by explicitly placing the "usbio"
driver at the end of the USB drivers list.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
For USB mass storage devices, we do not want to submit more bulk IN
packets than are required for the inbound data, since this will waste
memory.
Allow an upper limit to be specified on each refill attempt. The
endpoint will be refilled to the lower of this limit or the limit
specified by usb_refill_init().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Closing and reopening a USB endpoint will clear any halt status
recorded by the host controller, but may leave the endpoint halted at
the device. This will cause the first packet submitted to the
reopened endpoint to be lost, before the automatic stall recovery
mechanism detects the halt and resets the endpoint.
This is relatively harmless for USB network or HID devices, since the
wire protocols will recover gracefully from dropped packets. Some
protocols (e.g. for USB mass storage devices) assume zero packet loss
and so would be adversely affected.
Fix by allowing any device endpoint halt status to be cleared on a
freshly opened endpoint.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
There appears to be no reason for avoiding recursion when calling
ConnectController(), and recursion provides the least surprising
behaviour.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE is already capable of loading EFI drivers on demand (via
e.g. "chain UsbMassStorageDxe.efi") but there is currently no way to
trigger connection of the driver to any preexisting handles.
Add an explicit call to (re)connect all drivers after successfully
loading an image with a code type that indicates a boot services
driver.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A zero divisor will currently lead to a 16-bit integer overflow when
calculating the transmit padding, and a potential division by zero if
assertions are enabled.
Avoid these problems by treating a divisor value of zero as equivalent
to a divisor value of one (i.e. no alignment requirements).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The length as returned by UsbGetSupportedLanguages() should not
include the length of the descriptor header itself.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow temporary debugging code to call efi_wrap_systab() to obtain a
pointer to the wrapper EFI system table. This can then be used to
e.g. forcibly overwrite the boot services table pointer used by an
already loaded and running UEFI driver, in order to trace calls made
by that driver.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The call to UninstallMultipleProtocolInterfaces() will implicitly
disconnect any relevant controllers, and there is no specified
requirement to explicitly call DisconnectController() prior to
callling UninstallMultipleProtocolInterfaces().
However, some UEFI implementations (observed with the USB keyboard
driver on a Microsoft Surface Go) will fail to implicitly disconnect
the controller and will consequently fail to uninstall the protocols.
The net effect is that unplugging and replugging a USB keyboard may
leave the keyboard in a non-functional state.
Work around these broken UEFI implementations by including an
unnecessary call to DisconnectController() before the call to
UninstallMultipleProtocolInterfaces().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some UEFI USB drivers (e.g. the UsbKbDxe driver in EDK2) will react to
a reported EFI_USB_ERR_STALL by attempting to clear the endpoint halt.
This is redundant with iPXE's EFI_USB_IO_PROTOCOL implementation,
since endpoint stalls are cleared automatically by the USB core as
needed.
The UEFI USB driver's attempt to clear the endpoint halt can introduce
an unwanted 5 second delay per endpoint if the USB error was the
result of a device being physically removed, since the control
transfer will always time out.
Fix by reporting all USB errors as EFI_USB_ERR_SYSTEM instead of
EFI_USB_ERR_STALL.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some UEFI USB drivers (observed with the keyboard driver on a
Microsoft Surface Go) will react to an asynchronous USB transfer
failure by terminating the transfer from within the completion
handler. This closes the USB endpoint and, in the current
implementation, frees the containing structure.
This can lead to use-after-free bugs after the UEFI USB driver's
completion handler returns, since the calling code in iPXE expects
that a completion handler will not perform a control-flow action such
as terminating the transfer.
Fix by leaving the USB endpoint structure allocated until the device
is finally removed, as is already done (as an optimisation) for
control and bulk transfers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current error handling mechanism defers the endpoint reset until
the next use of the endpoint, on the basis that errors are detected
during completions and completion handling should not recursively call
usb_poll().
In the case of usb_control(), we are already at the level that calls
usb_poll() and can therefore safely perform the endpoint reset
immediately. This has no impact on functionality, but does make
debugging traces easier to read since the reset will appear
immediately after the causative error.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Retrieve the address windows and translation offsets for the
appropriate PCI root bridge and use them to adjust the PCI BAR address
prior to calling ioremap().
Originally-implemented-by: Pankaj Bansal <pankaj.bansal@nxp.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Define pci_ioremap() as a wrapper around ioremap() that could allow
for a non-zero address translation offset.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Older versions of gcc (observed with gcc 4.5.3) require attributes to
be specified on the first declaration of a symbol, and will silently
ignore attributes specified after the initial declaration. This
causes the ASN.1 OID-identified algorithms to end up misaligned.
Fix by adding __asn1_algorithm to the initial declarations in asn1.h.
Debugged-by: Dentcho Bankov <dbankov@vmware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently use a heuristic to determine whether or not to request
cable detection in PXE_OPCODE_INITIALIZE, based on the need to work
around a known Emulex driver bug (see commit c0b61ba "[efi] Work
around bugs in Emulex NII driver") and the need to accommodate links
that are legitimately slow to come up (see commit 6324227 "[efi] Skip
cable detection at initialisation where possible").
This heuristic appears to fail with newer Emulex drivers. Attempt to
support all known drivers (past and present) by first attempting
initialisation with cable detection, then falling back to attempting
initialisation without cable detection.
Reported-by: Kwang Woo Lee <kwleeyh@gmail.com>
Tested-by: Kwang Woo Lee <kwleeyh@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The file:/ URI syntax may be used to refer to local files on the
filesystem from which the iPXE binary was loaded. This is currently
implemented by directly using the DeviceHandle recorded in our
EFI_LOADED_IMAGE_PROTOCOL.
This mechanism will fail when a USB-enabled build of iPXE is loaded
from USB storage and subsequently installs its own USB host controller
drivers, since doing so will disconnect and reconnect the existing USB
storage drivers and thereby invalidate the original storage device
handle.
Fix by recording the device path for the loaded image's DeviceHandle
at initialisation time and later using the recorded device path to
locate the appropriate device handle.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The various USB specifications all use one-based numbering for ports.
This scheme is applied consistently across the various relevant
specifications, covering both port numbers that appear on the wire
(i.e. downstream hub port numbers) and port numbers that exist only
logically (i.e. root hub port numbers).
The UEFI specification is ambiguous about the port numbers as used for
the ParentPortNumber field within a USB_DEVICE_PATH structure. As of
UEFI specification version 2.8 errata B:
- section 10.3.4.5 just states "USB Parent Port Number" with no
indication of being zero-based or one-based
- section 17.1.1 notes that for the EFI_USB2_HC_PROTOCOL, references
to PortNumber parameters are zero-based for root hub ports
- section 17.1.1 also mentions a TranslatorPortNumber used by
EFI_USB2_HC_PROTOCOL, with no indication of being zero-based or
one-based
- there are no other mentions of USB port numbering schemes.
Experimentation and inspection of the EDK2 codebase reveals that at
least the EDK2 reference implementation will use zero-based numbering
for both root and non-root hub ports when populating a USB_DEVICE_PATH
structure (though will inconsistently use one-based numbering for the
TranslatorPortNumber parameter).
Use zero-based numbering for both root and non-root hub ports when
constructing a USB_DEVICE_PATH in order to match the behaviour of the
EDK2 implementation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This change fixes the offset used when retrieving the iPXE stack
pointer after a COM32 binary returns. The iPXE stack pointer is saved
at the top of the available memory then the the top of the stack for
the COM32 binary is set just below it. However seven more items are
pushed on the COM32 stack before the entry point is invoked so when
the COM32 binary returns the location of the iPXE stack pointer is 28
(and not 24) bytes above the current stack pointer.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
According to the latest UEFI specification (Version 2.8 Errata B)
p. 7.2:
"Buffer: A pointer to a pointer to the allocated buffer if the call
succeeds; undefined otherwise."
So implementations are obliged neither to return NULL, if the
allocation fails, nor to preserve the contents of the pointer.
Make the logic more reliable by checking the status code from
AllocatePool() instead of checking the returned pointer for NULL
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At the moment '\s*' is silently interpreted as just 's*', but in the
future it will be an error:
sed: 1: "s/\.o\s*:/_DEPS +=/": RE error: trailing backslash (\)
cf. https://bugs.freebsd.org/229925
Signed-off-by: Tobias Kortkamp <t@tobik.me>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Split debug message since eth_ntoa() uses a static result buffer.
Originally-fixed-by: Michael Bazzinotti <bazz@bazz1.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Fix memcmp() to return proper standard positive/negative values for
unequal comparisons. Current implementation is backwards (i.e. the
functions are returning negative when should be positive and
vice-versa).
Currently most consumers of these functions only check the return value
for ==0 or !=0 and so we can safely change the implementation without
breaking things.
However, there is one call that checks the polarity of this function,
and that is prf_sha1() for wireless WPA 4-way handshake. Due to the
incorrect memcmp() polarity, the WPA handshake creates an incorrect
PTK, and the handshake would fail after step 2. Undoubtedly, the AP
noticed the supplicant failed the mic check. This commit fixes that
issue.
Similar to commit 3946aa9 ("[libc] Fix strcmp()/strncmp() to return
proper values").
Signed-off-by: Michael Bazzinotti <bazz@bazz1.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This caused iPXE to reject images even when enough memory was
available.
Signed-off-by: David Decotigny <ddecotig@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
gensdsk currently creates a syslinux.cfg file that is invalid if the
filename ends in lkrn. Fix by setting the default target to label($b)
instead of filename($g).
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When no response is obtained from the first configured DNS server,
fall back to attempting the other configured servers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
All implemented socket openers provide definitions for both IPv4 and
IPv6 using exactly the same opener method. Simplify the logic by
omitting the address family from the definition.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Claiming the SNP devices has the side effect of raising the TPL to
iPXE's normal operating level of TPL_CALLBACK (see the commit message
for c89a446 ("[efi] Run at TPL_CALLBACK to protect against UEFI
timers") for details). This must happen before executing any code
that relies upon the TPL having been raised to TPL_CALLBACK.
The call to efi_snp_claim() in efi_download_start() currently happens
only after the call to xfer_open(). Calling xfer_open() will
typically result in a retry timer being started, which will result in
a call to currticks() in order to initialise the timer. The call to
currticks() will drop to TPL_APPLICATION and restore to TPL_CALLBACK
in order to allow a timer tick to occur. Since this call happened
before the call to efi_snp_claim(), the restored TPL is incorrect.
This in turn results in efi_snp_claim() recording the incorrect
original TPL, causing efi_snp_release() to eventually restore the
incorrect TPL, causing the system to lock up when ExitBootServices()
is called at TPL_CALLBACK.
Fix by moving the call to efi_snp_claim() to the start of
efi_download_start().
Debugged-by: Jarrod Johnson <jjohnson2@lenovo.com>
Debugged-by: He He4 Huang <huanghe4@lenovo.com>
Debugged-by: James Wang <jameswang@ami.com.tw>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The NUL byte included within the stack cookie to act as a string
terminator should be placed at the lowest byte address within the
stack cookie, in order to avoid potentially including the stack cookie
value within an accidentally unterminated string.
Suggested-by: Pete Beck <pete.beck@ioactive.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Several of the values used to compute a stack cookie (in the absence
of a viable entropy source) will tend to have either all-zeroes or
all-ones in the higher order bits. Rotate the values in order to
distribute the (minimal) available entropy more evenly.
Suggested-by: Pete Beck <pete.beck@ioactive.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Generalise the bit rotation implementations to use a common macro, and
add roll() and rorl() to handle unsigned long values.
Each function will still compile down to a single instruction.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The only remaining use case in iPXE for the CPU direction flag is in
__memcpy_reverse() where it is set to allow the use of "rep movsb" to
perform the memory copy. This matches the equivalent functionality in
the EDK2 codebase, which has functions such as InternalMemCopyMem that
also temporarily set the direction flag in order to use "rep movsb".
As noted in commit d2fb317 ("[crypto] Avoid temporarily setting
direction flag in bigint_is_geq()"), some UEFI implementations are
known to have buggy interrupt handlers that may reboot the machine if
a timer interrupt happens to occur while the direction flag is set.
Work around these buggy UEFI implementations by using the
(unoptimised) generic_memcpy_reverse() on i386 or x86_64 UEFI
platforms.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The UEFI specification states that the calling convention for IA-32
and x64 includes "Direction flag in EFLAGS is clear". This
specification covers only the calling convention used at the point of
calling functions annotated with EFIAPI. The specification explicitly
states that other functions (such as private functions or static
library calls) are not required to follow the UEFI calling
conventions.
The reference EDK2 implementation follows this specification. In
particular, the EDK2 interrupt handlers will clear the direction flag
before calling any EFIAPI functions, and will restore the direction
flag when returning from the interrupt handler. Some EDK2 private
library functions (most notably InternalMemCopyMem) may set the
direction flag temporarily in order to make efficient use of CPU
string operations.
The current implementation of iPXE's bigint_is_geq() for i386 and
x86_64 will similarly set the direction flag temporarily in order to
make efficient use of CPU string operations.
On some UEFI implementations (observed with a Getac RX10 tablet), a
timer interrupt that happens to occur while the direction flag is set
will reboot the machine. This very strongly indicates that the UEFI
timer interrupt handler is failing to clear the direction flag before
performing an affected operation (such as copying a block of memory).
Work around such buggy UEFI implementations by rewriting
bigint_is_geq() to avoid the use of string operations and so obviate
the requirement to temporarily set the direction flag.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A failure in device registration (e.g. due to a device with malformed
descriptors) will currently result in the port being disabled as part
of the error path. This in turn causes the hardware to detect the
device as newly connected, leading to an endless loop of failed device
registrations.
Fix by leaving the port enabled in the case of a registration failure.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When connected to a USB3 port, the AX88179 seems to have an
approximately 50% chance of producing a USB transaction error on each
of its three endpoints after being closed and reopened. The root
cause is unclear, but rewriting the USB device configuration value
seems to clear whatever internal error state has accumulated.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Experimentation shows that the existing 20ms delay is insufficient,
and often results in device detection being deferred until after iPXE
has completed startup.
Fix by increasing the delay to 100ms.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The driver-private data for root hubs is already set immediately after
allocating the USB bus. There seems to be no reason to set it again
when opening the root hub.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The "disabled" port states for USB2 and USB3 are not directly
equivalent. In particular, a disabled USB3 port will not detect new
device connections. The result is that a USB3 device disconnected
from and reconnected to an xHCI root hub port will end up reconnecting
as a USB2 device.
Fix by setting the link state to RxDetect after disabling the port, as
is already done during initialisation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The USB3 specification removes PORT_ENABLE from the list of features
that may be cleared via a CLEAR_FEATURE request. Experimentation
shows that omitting the attempt to clear PORT_ENABLE seems to result
in the correct hotplug behaviour.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Resetting the host endpoint may immediately restart any pending
transfers for that endpoint. If the device endpoint halt has not yet
been cleared, then this will probably result in a second failed
transfer.
This second failure may be detected within usb_endpoint_reset() while
waiting for usb_clear_feature() to complete. The endpoint will
subsequently be removed from the list of halted endpoints, causing the
second failure to be effectively ignored and leaving the host endpoint
in a permanently halted state.
Fix by deferring the host endpoint reset until after the device
endpoint is ready to accept new transfers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The ASIX USB NICs are capable of autodetecting the Ethernet link speed
and reporting it via PLSR but will not automatically update the
relevant GM and PS bits in MSR. The result is that a non-gigabit link
will fail to send or receive any packets.
The interrupt endpoint used to report link state includes the values
of the PHY BMSR and LPA registers. These are not sufficient to
differentiate between 100Mbps and 1000Mbps, since the LPA_NPAGE bit
does not necessarily indicate that the link partner is advertising
1000Mbps.
Extend axge_check_link() to write the MSR value based on the link
speed read from PLSR, and simplify the interrupt endpoint handler to
merely trigger a call to axge_check_link().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As per commit c89a446 ("[efi] Run at TPL_CALLBACK to protect against
UEFI timers") we expect to run at TPL_CALLBACK almost all of the time.
Various code paths rely on this assumption. Code paths that need to
temporarily lower the TPL (e.g. for entropy gathering) will restore it
to TPL_CALLBACK.
The entropy gathering code will be run during DRBG initialisation,
which happens during the call to startup(). In the case of iPXE
compiled as an EFI application this code will run within the scope of
efi_snp_claim() and so will execute at TPL_CALLBACK as expected.
In the case of iPXE compiled as an EFI driver the code will
incorrectly run at TPL_APPLICATION since there is nothing within the
EFI driver entry point that raises (and restores) the TPL. The net
effect is that a build that includes the entropy-gathering code
(e.g. a build with HTTPS enabled) will return from the driver entry
point at TPL_CALLBACK, which causes a system lockup.
Fix by raising and restoring the TPL within the EFI driver entry
point.
Debugged-by: Ignat Korchagin <ignat@cloudflare.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The EFI_RNG_PROTOCOL on the Microsoft Surface Go does not generate
random numbers. Successive calls to GetRNG() without any intervening
I/O operations (such as writing to the console) will produce identical
results. Successive reboots will produce identical results.
It is unclear what the Microsoft Surface Go is attempting to use as an
entropy source, but it is demonstrably producing zero bits of entropy.
The failure is already detected by the ANS-mandated Repetition Count
Test performed as part of our GetEntropy implementation. This
currently results in the entropy source being marked as broken, with
the result that iPXE refuses to perform any operations that require a
working entropy source.
We cannot use the existing EFI driver blacklisting mechanism to unload
the broken driver, since the RngDxe driver is integrated into the
DxeCore image.
Work around the broken driver by checking for consecutive identical
results returned by EFI_RNG_PROTOCOL and falling back to the original
timer-based entropy source.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some versions of gcc (observed with the cross-compiling gcc 9.3.0 in
Ubuntu 20.04) default to enabling -fPIE. Experimentation shows that
this results in the emission of R_AARCH64_ADR_GOT_PAGE relocation
records for __stack_chk_guard. These relocation types are not
supported by elf2efi.c.
Fix by explicitly disabling position-independent code for ARM64 EFI
builds.
Debugged-by: Antony Messerli <antony@mes.ser.li>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
GCC 10 emits warnings for implicit conversions of enumerated types.
The flexboot_nodnic code defines nodnic_queue_pair_type with values
identical to those of ib_queue_pair_type, and implicitly casts between
them. Add an explicit cast to fix the warning.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
GCC 10 produces a spurious warning about an out-of-bounds array access
for the unsized raw dword array in union intelvf_msg.
Avoid the warning by embedding the zero-length array within a struct.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
gcc10 switched default behavior from -fcommon to -fno-common. Since
"__shared" relies on the legacy behavior, explicitly specify it.
Signed-off-by: Bruce Rogers <brogers@suse.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Various implementation quirks in OCSP servers make it impractical to
use anything other than SHA1 to construct the issuerNameHash and
issuerKeyHash identifiers in the request certID. For example: both
the OpenCA OCSP responder used by ipxe.org and the Boulder OCSP
responder used by LetsEncrypt will fail if SHA256 is used in the
request certID.
As of commit 6ffe28a ("[ocsp] Accept response certID with missing
hashAlgorithm parameters") we rely on asn1_digest_algorithm() to parse
the algorithm identifier in the response certID. This will fail if
SHA1 is disabled via config/crypto.h.
Fix by using a direct ASN.1 object comparison on the OID within the
algorithm identifier.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Enable -fstack-protector for EFI builds, where binary size is less
critical than for BIOS builds.
The stack cookie must be constructed immediately on entry, which
prohibits the use of any viable entropy source. Construct a cookie by
XORing together various mildly random quantities to produce a value
that will at least not be identical on each run.
On detecting a stack corruption, attempt to call Exit() with an
appropriate error. If that fails, then lock up the machine since
there is no other safe action that can be taken.
The old conditional check for support of -fno-stack-protector is
omitted since this flag dates back to GCC 4.1.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some devices (observed with a Getac RX10 tablet and docking station
containing an embedded AX88179 USB NIC) seem to be capable of
detecting link state only during the call to Initialize(), and will
occasionally erroneously report that the link is down for the first
few such calls.
Work around these devices by retrying the Initialize() call multiple
times, terminating early if a link is detected. The eventual absence
of a link is treated as a non-fatal error, since it is entirely
possible that the link really is down.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Disable the use of MD5 as an OID-identifiable algorithm. Note that
the MD5 algorithm implementation will still be present in the build,
since it is used implicitly by various cryptographic components such
as HTTP digest authentication; this commit removes it only from the
list of OID-identifiable algorithms.
It would be appropriate to similarly disable the use of SHA-1 by
default, but doing so would break the use of OCSP since several OCSP
responders (including the current version of openca-ocspd) are not
capable of interpreting the hashAlgorithm field and so will fail if
the client uses any algorithm other than the configured default.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
There are many ways in which the object for a cryptographic algorithm
may be included, even if not explicitly enabled in config/crypto.h.
For example: the MD5 algorithm is required by TLSv1.1 or earlier, by
iSCSI CHAP authentication, by HTTP digest authentication, and by NTLM
authentication.
In the current implementation, inclusion of an algorithm for any
reason will result in the algorithm's ASN.1 object identifier being
included in the "asn1_algorithms" table, which consequently allows the
algorithm to be used for any ASN1-identified purpose. For example: if
the MD5 algorithm is included in order to support HTTP digest
authentication, then iPXE would accept a (validly signed) TLS
certificate using an MD5 digest.
Split the ASN.1 object identifiers into separate files that are
required only if explicitly enabled in config/crypto.h. This allows
an algorithm to be omitted from the "asn1_algorithms" table even if
the algorithm implementation is dragged in for some other purpose.
The end result is that only the algorithms that are explicitly enabled
in config/crypto.h can be used for ASN1-identified purposes such as
signature verification.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The supported ciphers and digest algorithms may already be specified
via config/crypto.h. Extend this to allow a minimum TLS protocol
version to be specified.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some platforms (observed with an AMI BIOS on an Apollo Lake system)
will spuriously fail the call to ConnectController() when the UEFI
network stack is disabled. This appears to be a BIOS bug that also
affects attempts to connect any non-iPXE driver to the NIC controller
handle via the UEFI shell "connect" utility.
Work around this BIOS bug by falling back to calling our
efi_driver_start() directly if the call to ConnectController() fails.
This bypasses any BIOS policy in terms of deciding which driver to
connect but still cooperates with the UEFI driver model in terms of
handle ownership, since the use of EFI_OPEN_PROTOCOL_BY_DRIVER ensures
that the BIOS is aware of our ownership claim.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The URI parsing code for "host[:port]" checks that the final character
is not ']' in order to allow for IPv6 literals. If the entire
"host[:port]" portion of the URL is an empty string, then this will
access the preceding character. This does not result in accessing
invalid memory (since the string is guaranteed by construction to
always have a preceding character) and does not result in incorrect
behaviour (since if the string is empty then strrchr() is guaranteed
to return NULL), but it does make the code confusing to read.
Fix by inverting the order of the two tests.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As described in the previous commit, work around a UEFI specification
bug that necessitates calling UnloadImage if the return value from
LoadImage is EFI_SECURITY_VIOLATION.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently assumes that any error returned from LoadImage()
indicates that the image was not loaded. This assumption was correct
at the time the code was written and remained correct for UEFI
specifications up to and including version 2.1.
In version 2.3, the UEFI specification broke API and ABI compatibility
by defining that a return value of EFI_SECURITY_VIOLATION would now
indicate that the image had been loaded and a valid image handle had
been created, but that the image should not be started.
The wording in version 2.2 is ambiguous, and does not define whether
or not a return value of EFI_SECURITY_VIOLATION indicates that a valid
image handle has been created.
Attempt to work around all of these incompatible and partially
undefined APIs by calling UnloadImage if we get a return value of
EFI_SECURITY_VIOLATION. Minimise the risk of passing an uninitialised
pointer to UnloadImage by setting ImageHandle to NULL prior to calling
LoadImage.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Reduce the size of the USB disk image in the common case that
CONSOLE_INT13 is not enabled.
Originally-implemented-by: Romain Guyard <romain.guyard@mujin.co.jp>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Eliminate an unnecessary variable-length stack allocation and memory
copy by allowing TFTP option processors to modify the option string
in-place.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
According to UEFI specification 2.8 p 24.1 we must set the
EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit in the "Disable" mask, when
"ResetMCastFilter" is TRUE.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Split-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Currently, if the SNP driver for whatever reason fails to enable
receive filters for multicast frames, it falls back to enabling just
unicast and broadcast filters. This breaks some IPv6 functionality as
the network card does not respond to neighbour solicitation requests.
Some cards refuse to enable EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST, but
do support enabling EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST,
so try it before falling back to just unicast+broadcast.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Split-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow a PeerDist hosted cache server to be specified via the
${peerhost} setting, e.g.:
# Use 192.168.0.1 as hosted cache server
set peerhost 192.168.0.1
Note that this simply treats the hosted cache server as a permanently
discovered peer for all segments.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the use of PeerDist content encoding to be enabled or disabled
via the ${peerdist} setting, e.g.:
# Disable PeerDist
set peerdist 0
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On devices with no EEPROM or OTP, the MAC_CR register defaults to not
using automatic link speed detection, with the result that no packets
are successfully sent or received.
Fix by always enabling automatic speed and duplex detection, since
iPXE provides no mechanism for manual configuration of either link
speed or duplex.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On at least some platforms (observed with a Raspberry Pi), any attempt
to perform USB transfers via EFI_USB_IO_PROTOCOL during EFI shutdown
will lock up the system. This is quite probably due to the already
documented failure of all EFI timers when ExitBootServices() is
called: see e.g. commit 5cf5ffea2 "[efi] Work around temporal anomaly
encountered during ExitBootServices()".
Work around this problem by refusing to poll endpoints if shutdown is
in progress, and by immediately failing any attempts to enqueue new
transfers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The USB core reuses the I/O buffer space occupied by the USB setup
packet to hold the completion status for message transfers, assuming
that the message() method will always strip the setup packet before
returning. This assumption is correct for all of the hardware
controller drivers (XHCI, EHCI, and UHCI), since these drivers are
able to enqueue the transfer as a separate action from waiting for the
transfer to complete.
The EFI_USB_IO_PROTOCOL does not allow us to separate actions in this
way: there is only a single blocking method that both enqueues and
waits for completion. Our usbio driver therefore currently defers
stripping the setup packet until the control endpoint is polled.
This causes a bug if a message transfer is enqueued but never polled
and is subsequently cancelled, since the cancellation will be reported
with the I/O buffer still containing the setup packet. This breaks
the assumption that the setup packet has been stripped, and triggers
an assertion failure in usb_control_complete().
Fix by always stripping the setup packet in usbio_endpoint_message(),
and adjusting usbio_control_poll() to match.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Ensure that the configured RSA digestInfo prefixes are included in any
build that includes rsa.o (rather than relying on x509.o or tls.o also
being present in the final binary).
This allows the RSA self-tests to be run in isolation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The restart of negotiation triggered by a HelloRequest currently does
not call tls_tx_resume() and so may end up leaving the connection in
an idle state in which the pending ClientHello is never sent.
Fix by calling tls_tx_resume() as part of tls_restart(), since the
call to tls_tx_resume() logically belongs alongside the code that sets
bits in tls->tx_pending.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Raw block downloads are expensive if the origin server uses HTTPS,
since each concurrent download will require local TLS resources
(including potentially large received encrypted data buffers).
Raw block downloads may also be prohibitively slow to initiate when
the origin server is using HTTPS and client certificates. Origin
servers for PeerDist downloads are likely to be running IIS, which has
a bug that breaks session resumption and requires each connection to
go through the full client certificate verification.
Limit the total number of concurrent raw block downloads to ameliorate
these problems.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Move the responsibility for starting the block download timers from
peerblk_expired() to peerblk_raw_open() and peerblk_retrieval_open(),
in preparation for adding the ability to defer calls to
peerblk_raw_open() via a block download queue.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add a build shortcut "rpi", allowing for e.g.
make CONFIG=rpi CROSS=aarch64-linux-gnu- bin-arm64-efi/rpi.efi
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The (very approximate) split between Makefile.housekeeping and
Makefile is that the former provides mechanism and the latter provides
policy.
Provide a section within Makefile as a home for predefined build
shortcuts such as the existing all-drivers build.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The WORKAROUND_CFLAGS list is constructed based on running tests on
the target compiler, and the results may not be valid for the host
compiler.
The only relevant workaround required for the host compiler is
-Wno-stringop-truncation, which is needed to avoid a spurious compiler
warning for a totally correct usage of strncpy() in util/elf2efi.c.
Duplicating the workaround tests for the host compiler is messy, as is
conditionally applying __attribute__((nonstring)). Fix instead by
disapplying WORKAROUND_CFLAGS for the host compiler, and using
memcpy() with an explicitly calculated length instead of strncpy() in
util/elf2efi.c.
Reported-by: Ignat Korchagin <ignat@cloudflare.com>
Reported-by: Christopher Clark <christopher.w.clark@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Compiling with gcc 9.1 generates lots of "taking address of packed
member of ... may result in an unaligned pointer value" warnings.
Some of these warnings are genuine, and indicate correctly that parts
of iPXE currently require the CPU (or runtime environment) to support
unaligned accesses. For example: the TCP/IP receive data path will
attempt to access 32-bit fields that may not be aligned to a 32-bit
boundary.
Other warnings are either spurious (such as when the pointer is to a
variable-length byte array, which can have no alignment requirement
anyway) or unhelpful (such as when the pointer is used solely to
provide a debug colour value for the DBGC() macro).
There appears to be no easy way to silence the spurious warnings.
Since the ability to perform unaligned accesses is already a
requirement for iPXE, work around the problem by silencing this class
of warnings.
Signed-off-by: Valentine Barshak <gvaxon@gmail.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use '%p' directive, and print handle's address if the address is null
and the handle doesn't have a name. This fixes the following
compilation error:
interface/efi/efi_debug.c:334:3: error: '%s' directive
argument is null [-Werror=format-overflow=]
Signed-off-by: Valentine Barshak <gvaxon@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Raspberry Pi NIC has no EEPROM to hold the MAC address. The
platform firmware (e.g. UEFI or U-Boot) will typically obtain the MAC
address from the VideoCore firmware and add it to the device tree,
which is then made available to subsequent programs such as iPXE or
the Linux kernel.
Add the ability to parse a flattened device tree and to extract the
MAC address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
efidev_parent() currently assumes that any device with BUS_TYPE_EFI is
part of a struct efi_device. This assumption is not valid, since the
code in efi_device_info() may also create a device with BUS_TYPE_EFI.
Fix by searching through the list of registered EFI devices when
looking for a match, instead of relying on the bus type value.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
It is currently not possible to build the all-drivers iPXE binaries
for ARM, since there is no implementation for inb(), outb(), etc.
There is no common standard for accessing I/O space on ARM platforms,
and there are almost no ARM-compatible peripherals that actually
require I/O space accesses.
Provide dummy implementations that behave as though no device is
present (i.e. ignore writes, return all bits high for reads). This is
sufficient to allow the all-drivers binaries to link, and should cause
drivers to behave as though no I/O space peripherals are present in
the system.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 1a7746603 ("[build] Fix use of inline assembly on GCC 4.8 ARM64
builds") switched from using "%c0" to "%a0" in order to avoid an
"invalid operand prefix" error on the ARM64 version of GCC 4.8.
It appears that the ARM64 version of GCC 8 now produces an "invalid
address mode" error for the "%a0" form, but is happy with the original
"%c0" form.
Switch back to using the "%c0" form, on the assumption that the
requirement for "%a0" was a temporary aberration.
Originally-fixed-by: John L. Jolly <jjolly@suse.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The physical function defaults to operating in "PXE mode" after a
power-on reset. In this mode, receive descriptors are fetched and
written back as single descriptors. In normal (non-PXE mode)
operation, receive descriptors are fetched and written back only as
complete cachelines unless an interrupt is raised.
There is no way to return to PXE mode from non-PXE mode, and there is
no way for the virtual function driver to operate in PXE mode.
Choose to operate in non-PXE mode. This requires us to trick the
hardware into believing that it is raising an interrupt, so that it
will not defer writing back receive descriptors until a complete
cacheline (i.e. four packets) have been consumed. We do so by
configuring the hardware to use MSI-X with a dummy target location in
place of the usual APIC register.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The virtual function driver will use the same transmit and receive
descriptor ring structures, but will not itself construct and program
the ring context. Split out ring creation and destruction from the
programming of the ring context, to allow code to be shared between
physical and virtual function drivers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The virtual function transmit and receive ring tail register offsets
do not match those of the physical function. Allow the tail register
offsets to be specified separately.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The physical function driver does not allow the virtual function to
request the use of 16-byte receive descriptors. Switch to using
32-byte receive descriptors.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide a weak stub function for handling the "send to VF" event used
for communications between the physical and virtual function drivers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The "send to PF" and "send to VF" admin queue descriptors (ab)use the
cookie field to hold the extended opcode and return code values.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A virtual function reset is triggered via an admin queue command and
will reset the admin queue configuration registers. Allow the admin
queues to be reinitialised after such a reset, without requiring the
overhead (and potential failure paths) of freeing and reallocating the
queues.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently use a single data buffer shared between all admin queue
descriptors. This works for the physical function driver since we
have at most one command in progress and only a single event (which
does not use a data buffer).
The communication path between the physical and virtual function
drivers uses the event data buffer, and there is no way to prevent a
solicited event (i.e. a response to a request) from being overwritten
by an unsolicited event (e.g. a link status change).
Provide individual data buffers for each admin event queue descriptor
(and for each admin command queue descriptor, for the sake of
consistency).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The register map for the virtual functions appears to have been
constructed using a random number generator.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The physical function driver does not allow the virtual function to
request that VLAN tags are left unstripped. Extract and use the VLAN
tag from the receive descriptor if present.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Hermon driver uses vlan_find() to identify the appropriate VLAN
device for packets that are received with the VLAN tag already
stripped out by the hardware. Generalise this capability and expose
it for use by other network card drivers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Intel 40 Gigabit Ethernet virtual functions support only MSI-X
interrupts, and will write back completed interrupt descriptors only
when the device attempts to raise an interrupt (or when a complete
cacheline of receive descriptors has been completed).
We cannot actually use MSI-X interrupts within iPXE, since we never
have ownership of the APIC. However, an MSI-X interrupt is
fundamentally just a DMA write of a single dword to an arbitrary
address. We can therefore configure the device to "raise" an
interrupt by writing a meaningless value to an otherwise unused memory
location: this is sufficient to trigger the receive descriptor
writeback logic.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
One of the design goals of ASN.1 DER is to provide a canonical
serialization of a data structure, thereby allowing for equality of
values to be tested by simply comparing the serialized bytes.
Some OCSP servers will modify the request certID to omit the optional
(and null) "parameters" portion of the hashAlgorithm. This is
arguably legal but breaks the ability to perform a straightforward
bitwise comparison on the entire certID field between request and
response.
Fix by comparing the OID-identified hashAlgorithm separately from the
remaining certID fields.
Originally-fixed-by: Thilo Fromm <Thilo@kinvolk.io>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide increased visibility into the progress of TCP connections by
displaying an explicit "connecting" status message while waiting for
the TCP handshake to complete.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
TLS connections will almost always create background connections to
perform cross-signed certificate downloads and OCSP checks. There is
currently no direct visibility into which checks are taking place,
which makes troubleshooting difficult in the absence of either a
packet capture or a debug build.
Use the job progress message buffer to report the current cross-signed
certificate download or OCSP status check, where applicable.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Record the session ID (if any) provided by the server and attempt to
reuse it for any concurrent connections to the same server.
If multiple connections are initiated concurrently (e.g. when using
PeerDist) then defer sending the ClientHello for all but the first
connection, to allow time for the first connection to potentially
obtain a session ID (and thereby speed up the negotiation for all
remaining connections).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On a Dell OptiPlex 7010, calling DisconnectController() on the LOM
device handle will lock up the system. Debugging shows that execution
is trapped in an infinite loop that is somehow trying to reconnect
drivers (without going via ConnectController()).
The problem can be reproduced in the UEFI shell with no iPXE code
present, by using the "disconnect" command. Experimentation shows
that the only fix is to unload (rather than just disconnect) the
"Ip4ConfigDxe" driver.
Add the concept of a blacklist of UEFI drivers that will be
automatically unloaded when iPXE runs as an application, and add the
Dell Ip4ConfigDxe driver to this blacklist.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Option::ROM module recognizes and checks EFI header of image. The
disrom.pl utility dumps this header if is present.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Option::ROM module now compares the Code Type in the PCIR header
to 0x00 (PC-AT) in order to check the presence of other header types
(PnP, UNDI, iPXE, etc). The validity of these headers are checked not
only by offset, but by range and signature checks also. The image
checksum and initial size also depends on Code Type.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
GCC 9 warns that abs() may truncate its signed long argument. Fix by
using labs() instead.
Reported-by: Martin Liška <mliska@suse.cz>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Fix strcmp() and strncmp() to return proper standard positive/negative
values for unequal strings. Current implementation is backwards
(i.e. the functions are returning negative when should be positive and
vice-versa).
Currently all consumers of these functions only check the return value
for ==0 or !=0 and so we can safely change the implementation without
breaking things.
Signed-off-by: Aaron Young <Aaron.Young@oracle.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Current (simplified):
1. InstallMultipleProtocolInterfaces
if err goto err_install_protocol_interface;
2. OpenProtocol(efi_nii_protocol_guid)
if err goto err_open_nii;
3. OpenProtocol(efi_nii31_protocol_guid)
if err goto err_open_nii31;
4. efi_child_add
if err goto err_efi_child_add;
...
err_efi_child_add:
CloseProtocol(efi_nii_protocol_guid) <= should be efi_nii31_protocol_guid
err_open_nii: <= should be err_open_nii31
CloseProtocol(efi_nii31_protocol_guid) <= should be efi_nii_protocol_guid
err_open_nii31: <= should be err_open_nii
UninstallMultipleProtocolInterfaces
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
PCI Configuration Space contains fields prog-if at the offset 0x09,
sub-class at the offset 0x0a and base-class at the offset 0x0b (it
respects little endian). PCIR structure uses these fields in the same
order.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Starting from binutils 2.31.0 (commit bd7ab16b) x86-64 assembler
generates R_X86_64_PLT32 instead of R_X86_64_PC32.
Acked-by: John Jolly <jjolly@suse.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The first adapters in this family are X2522-10, X2522-25, X2541 and
X2542.
These no longer use PCI BAR 0 for I/O, but use that for memory. In
other words, BAR 2 on SFN8xxx adapters now becomes BAR 0.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Devices that support jumbo frames will currently default to the
largest possible MTU. This assumption is valid for virtual adapters
such as virtio-net, where the MTU must have been configured by a
system administrator, but is unsafe in the general case of a physical
adapter.
Default to the standard Ethernet MTU, unless explicitly overridden
either by the driver or via the ${netX/mtu} setting.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid calling rndis_halt() and rndis->op->close() twice if the call to
register_netdev() fails.
Reported-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some versions of gcc seem to silently accept an attempt to disable an
unrecognised warning (e.g. via -Wno-stringop-truncation) but will then
report the unrecognised warning if any other error occurs during the
build, resulting in a potentially misleading error message.
Avoid this potential confusion by using the positive-form tests in
order to determine the workaround CFLAGS.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The definition of version_response channel message in Linux doesn't
include version field, so the upcoming VMBus implementation in QEMU
doesn't set it either. Neither Windows nor Linux had any problem with
this.
The check against this field is redundant because the message is the
response to initiate_contact message containing the specific version
requested, so the response with version_supported=true is unambiguous.
Drop this check and don't rely on the field to be present in the
message.
Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
register_netdev expects ->hw_addr and ->ll_addr to be already filled,
so move it towards the end of register_rndis, after the respective
fields have been successfully queried from the underlying device.
Signed-off-by: Roman Kagan <rkagan@virtuozzo.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The gcc 8 compiler introduces a warning for certain string
manipulation functions, flagging usages which _may_ not be intended.
An audit of the iPXE sources indicates all usages of strncat and
strncpy are as intended, so the warnings currently issued are not
helpful, especially if warnings are considered errors.
Fix by detecting gcc's support for -Wno-stringop-truncation and, if
detected, using that option to avoid the warning.
Signed-off-by: Bruce Rogers <brogers@suse.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Also-fixed-by: Christian Hesse <list@eworm.de>
Also-fixed-by: Roman Kagan <rkagan@virtuozzo.com>
Also-fixed-by: Bernhard M. Wiedemann <bwiedemann@suse.de>
Also-fixed-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As pointedly documented in RFC7230 section 2.3, HTTP is a stateless
protocol: each request message can be understood in isolation from any
other requests or responses. Various authentication schemes such as
NTLM break this fundamental property of HTTP and rely on the same TCP
connection being reused.
Work around these broken authentication schemes by ensuring that the
most recently pooled connection is reused for the subsequent
authentication retry.
Reported-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Tested-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add the function mii_find() in order to locate the PHY address.
Signed-off-by: Sylvie Barlow <sylvie.c.barlow@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently have no generic concept of a PHY address, since all
existing implementations simply hardcode the PHY address within the
MII access methods.
A bit-bashing MII interface will need to be provided with an explicit
PHY address in order to generate the correct waveform. Allow for this
by separating out the concept of a MII device (i.e. a specific PHY
address attached to a particular MII interface).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the subsystem IDs to be used when checking for PXE stacks with
broken interrupt support.
Suggested-by: Levi Hsieh <Levi.Hsieh@dell.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The relocation type R_ARM_REL32 is generated when building
bin-arm32-efi/snp.efi using gcc 6.3 and ld 2.28.
R_ARM_REL32 is a program counter (PC) relative 32 bit relocation so we
can ignore it like all other PC relative relocations.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When booting some versions of the UEFI shell, our driver binding
protocol's Supported() entry point is called at TPL_NOTIFY for no
discernible reason. Attempting to raise to TPL_CALLBACK triggers an
immediate assertion failure in the firmware.
Since our Supported() method can run at any TPL, fix by simply not
attempting to raise the TPL within this method.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Release SNP devices to allow the SAN booted image to use our
EFI_SIMPLE_NETWORK_PROTOCOL instance, and to ensure that the image is
started at TPL_APPLICATION.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The cipherstream xfer_window_changed() message is used to retrigger
the TLS transmit state machine. If the transmit state machine is
idle, then the window change message will not be propagated to the
plainstream interface. This can potentially cause the plainstream
interface peer (e.g. httpcore) to block waiting for a window change
message that will never arrive.
Fix by ensuring that the window change message is propagated to the
plainstream interface if the transmit state machine is idle. (If the
transmit state machine is not idle then the plainstream window will be
zero anyway.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
In TLS terminology a session conceptually spans multiple individual
connections, and essentially represents the stored cryptographic state
(master secret and cipher suite) required to establish communication
without going through the certificate and key exchange handshakes.
Rename tls_session to tls_connection in order to make the name
tls_session available to represent the session state.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A failure in tls_generate_random() will result in a call to ref_put()
before the received data list has been initialised, which will cause
free_tls() to attempt to traverse an uninitialised list.
Fix by ensuring that all fields referenced by free_tls() are
initialised before any of the potential failure paths.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 6149e0a ("[librm] Provide symbols for inline code placed into
other sections") may cause build failures due to duplicate label names
if the compiler chooses to duplicate inline assembly code.
Fix by using the "%=" special format string to include a
guaranteed-unique number within the label name.
The "%=" will be expanded only if constraints exist for the inline
assembly. This fix therefore requires that all REAL_CODE() fragments
use a (possibly empty) constraint list.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide symbols constructed from the object name and line number for
code fragments placed into alternative sections, such as inline
REAL_CODE() assembly placed into .text16. This simplifies the
debugging task of finding the source code corresponding to a given
instruction pointer.
Note that we cannot use __FUNCTION__ since it is not a preprocessor
macro and so cannot be concatenated with string literals.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
If the underlying PXE stack reports an invalid IRQ number (above
IRQ_MAX), treat this as equivalent to an empty IRQ number and fall
back to using polling mode.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The existence of MMX and SSE is required by the System V x86_64 ABI
and so is assumed by gcc, but these registers are not preserved by our
own interrupt handlers and are unlikely to be preserved by other
context switch handlers in a boot firmware environment.
Explicitly prevent gcc from using MMX or SSE registers to avoid
potential problems due to silent register corruption.
We must remove the %xmm0-%xmm5 clobbers from the x86_64 version of
hv_call() since otherwise gcc will complain about unknown register
names. Theoretically, we should probably add code to explicitly
preserve the %xmm0-%xmm5 registers across a hypercall, in order to
guarantee to external code that these registers remain unchanged. In
practice this is difficult since SSE registers are disabled by
default: for background information see commits 71560d1 ("[librm]
Preserve FPU, MMX and SSE state across calls to virt_call()") and
dd9a14d ("[librm] Conditionalize the workaround for the Tivoli VMM's
SSE garbling").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently perform various min-entropy calculations using build-time
floating-point arithmetic. No floating-point code ends up in the
final binary, since the results are eventually converted to integers
and asserted to be compile-time constants.
Though this mechanism is undoubtedly cute, it inhibits us from using
"-mno-sse" to prevent the use of SSE registers by the compiler.
Fix by using fixed-point arithmetic instead.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This is required to work around a bug in some firmware versions.
Signed-off-by: Ameer Mahagneh <ameerm@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the ACPI power management timer to be used if enabled via
TIMER_ACPI in config/timer.h. This provides an alternative timer on
systems where the standard 8254 PIT is unavailable or unreliable.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some drivers are known to call the optional Map_Mem() callback without
first checking that the callback exists. Provide a usable basic
implementation of Map_Mem() along with the other callbacks that become
mandatory if Map_Mem() is provided.
Note that in theory the PCI I/O protocol is allowed to require
multiple calls to Map(), with each call handling only a subset of the
overall mapped range. However, the reference implementation in EDK2
assumes that a single Map() will always suffice, so we can probably
make the same simplifying assumption here.
Tested with the Intel E3522X2.EFI driver (which, incidentally, fails
to cleanly remove one of its mappings).
Originally-implemented-by: Maor Dickman <maord@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The blocked link test in eth_slow_lacp_rx() is performed before the
actor TLV is copied to the partner TLV, and so must test the actor
state field rather than the partner state field.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some CAs provide non-functional OCSP servers, and some clients are
forced to operate on networks without access to the OCSP servers.
Allow the user to explicitly disable the use of OCSP checks by
undefining OCSP_CHECK in config/crypto.h.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Limit the profile sample count to INT_MAX to avoid both signed
overflow and a potential division by zero when updating the stored
mean value.
Signed-off-by: Michael Brown <mcb30@ipxe.org>