Commit Graph

6500 Commits (6714b20ea20af5046cdb36b58ab777b55a3c003c)

Author SHA1 Message Date
Michael Brown f0b1025503 [efi] Unload vetoed drivers by image handle rather than driver handle
In most cases, the driver handle will be the image handle itself.
However, this is not required by the UEFI specification, and some
images will install multiple driver binding handles.

Use the image handle (extracted from the driver binding protocol
instance) when attempting to unload the driver's image.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-23 16:51:10 +01:00
Michael Brown c832580f19 [efi] Pass more detailed driver information to veto methods
Pass the driver binding handle, the driver binding protocol instance,
the image handle, and the loaded image protocol instance to all veto
methods.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-23 16:22:27 +01:00
Michael Brown 9a118322a0 [efi] Show manufacturer in veto debug output
Simplify the process of adding new entries to the veto list by
including the manufacturer name within the standard debug output.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-22 23:20:37 +01:00
Michael Brown 2689a6e776 [efi] Always poll for TX completions
Polling for TX completions is arguably redundant when there are no
transmissions currently in progress.  Commit c6c7e78 ("[efi] Poll for
TX completions only when there is an outstanding TX buffer") switched
to setting the PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS flag only when
there is an in-progress transmission awaiting completion, in order to
reduce reported TX errors and debug message noise from buggy NII
implementations that report spurious TX completions whenever the
transmit queue is empty.

Some other NII implementations (observed with the Realtek driver in a
Dell Latitude 3440) seem to have a bug in the transmit datapath
handling which results in the transmit ring freezing after sending a
few hundred packets under heavy load.  The symptoms are that the
TPPoll register's NPQ bit remains set and the 256-entry transmit ring
contains a large number of uncompleted descriptors (with the OWN bit
set), the first two of which have identical data buffer addresses.

Though iPXE will submit at most one in-progress transmission via NII,
the Dell/Realtek driver seems to make a page-aligned copy of each
transmit data buffer and to report TX completions immediately without
waiting for the packet to actually be transmitted.  These synthetic TX
completions continue even after the hardware transmit ring freezes.

Setting PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS on every poll reduces the
probability of this Dell/Realtek driver bug being triggered by a
factor of around 500, which brings the failure rate down to the point
that it can sensibly be managed by external logic such as the
"--timeout" option for image downloads.  Closing and reopening the
interface (via "ifclose"/"ifopen") will clear the error condition and
allow transmissions to resume.

Revert to setting PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS on every poll,
and silently ignore situations in which the hardware reports a
completion when no transmission is in progress.  This approximately
matches the behaviour of the SnpDxe driver, which will also generally
set PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS on every poll.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-21 11:49:53 +01:00
Michael Brown 4fa4052c7e [efi] Provide read-only access to EFI variables via settings mechanism
EFI variables do not map neatly to the iPXE settings mechanism, since
the EFI variable identifier includes a namespace GUID that cannot
cleanly be supplied as part of a setting name.  Creating a new EFI
variable requires the variable's attributes to be specified, which
does not fit within iPXE's settings concept.

However, EFI variable names are generally unique even without the
namespace GUID, and EFI does provide a mechanism to iterate over all
existent variables.  We can therefore provide read-only access to EFI
variables by comparing only the names and ignoring the namespace
GUIDs.

Provide an "efi" settings block that implements this mechanism using a
syntax such as:

  echo Platform language is ${efi/PlatformLang:string}

  show efi/SecureBoot:int8

Settings are returned as raw binary values by default since an EFI
variable may contain boolean flags, integer values, ASCII strings,
UCS-2 strings, EFI device paths, X.509 certificates, or any other
arbitrary blob of data.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-09 14:37:44 +01:00
Michael Brown 25a3d3acab [efi] Veto the VMware UefiPxeBcDxe driver
The EDK2 UefiPxeBcDxe driver includes some remarkably convoluted and
unsafe logic in its driver binding protocol Start() and Stop() methods
in order to support a pair of nominally independent driver binding
protocols (one for IPv4, one for IPv6) sharing a single dynamically
allocated data structure.  This PXEBC_PRIVATE_DATA structure is
installed as a dummy protocol on the NIC handle in order to allow both
IPv4 and IPv6 driver binding protocols to locate it as needed.

The error handling code path in the UefiPxeBcDxe driver's Start()
method may attempt to uninstall the dummy protocol but fail to do so.
This failure is ignored and the containing memory is subsequently
freed anyway.  On the next invocation of the driver binding protocol,
it will find and use this already freed block of memory.  At some
point another memory allocation will occur, the PXEBC_PRIVATE_DATA
structure will be corrupted, and some undefined behaviour will occur.

The UEFI firmware used in VMware ESX 8 includes some proprietary
changes which attempt to install copies of the EFI_LOAD_FILE_PROTOCOL
and EFI_PXE_BASE_CODE_PROTOCOL instances from the IPv4 child handle
onto the NIC handle (along with a VMware-specific protocol with GUID
5190120d-453b-4d48-958d-f0bab3bc2161 and a NULL instance pointer).
This will inevitably fail with iPXE, since the NIC handle already
includes an EFI_LOAD_FILE_PROTOCOL instance.

These VMware proprietary changes end up triggering the unsafe error
handling code path described above.  The typical symptom is that an
attempt to exit from iPXE back to the UEFI firmware will crash the VM
with a General Protection fault from within the UefiPxeBcDxe driver:
this happens when the UefiPxeBcDxe driver's Stop() method attempts to
call through a function pointer in the (freed) PXEBC_PRIVATE_DATA
structure, but the function pointer has by then been overwritten by
UCS-2 character data from an unrelated memory allocation.

Work around this failure by adding the VMware UefiPxeBcDxe driver to
the driver veto list.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-08 12:24:07 +01:00
Michael Brown 8ab9bdca4f [efi] Include protocol interface address in debug output
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-08 11:15:27 +01:00
Michael Brown 12776acce5 [efi] Add UefiPxeBcDxe module GUID
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07 13:00:24 +01:00
Michael Brown 367e022b5e [efi] Add HttpBootDxe module GUID
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07 13:00:24 +01:00
Michael Brown b9a60fb0b7 [efi] Add new IScsiDxe module GUID
The old IPv4-only IScsiDxe driver in MdeModulePkg/Universal/Network
was replaced by a dual-stack IScsiDxe driver in NetworkPkg.

Add the module GUID for this driver.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07 12:57:51 +01:00
Michael Brown a64764d10f [efi] Add HTTP header and GUID definitions
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07 12:57:51 +01:00
Michael Brown bc75bbaf17 [efi] Add DNS headers and GUID definitions
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07 12:57:51 +01:00
Michael Brown e7adf5701f [efi] Add Ip4Config2 header and GUID definition
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07 12:57:51 +01:00
Michael Brown 92ab2de3a4 [efi] Add IPv6 versions of existing IPv4 headers and GUID definitions
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07 12:27:06 +01:00
Michael Brown 3184ff74eb [efi] Update to current EDK2 headers
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07 12:24:42 +01:00
Michael Brown 9cb0a4b8ec [efi] Disable static assertions in EFI headers on non-EFI platforms
The EDK2 headers may be included even in builds for non-EFI platforms.
Commits such as 9de6c45 ("[arm] Use -fno-short-enums for all 32-bit
ARM builds") have so far ensured that the compile-time checks within
the EDK2 headers will pass even when building for a non-EFI platform.

As a more general solution, temporarily disable static assertions
while including UefiBaseType.h if building on a non-EFI platform.
This avoids the need to modify the ABI on other platforms.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-07 12:24:03 +01:00
Michael Brown b0093571f8 [crypto] Add support for PKCS#8 private key format
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-06-02 13:54:42 +01:00
Michael Brown 6a7f560e60 [efi] Implement "shim" as a dummy command on non-EFI platforms
The "shim" command will skip downloading the shim binary (and is
therefore a conditional no-op) if there is already a selected EFI
image that can be executed directly via LoadImage()/StartImage().
This allows the same iPXE script to be used with Secure Boot either
enabled or disabled.

Generalise this further to provide a dummy "shim" command that is an
unconditional no-op on non-EFI platforms.  This then allows the same
iPXE script to be used for BIOS, EFI with Secure Boot disabled, or EFI
with Secure Boot enabled.

The same effect could be achieved by using "iseq ${platform} efi"
within the script, but this would complicate end-user documentation.

To minimise the code size impact, the dummy "shim" command is a pure
no-op that does not call parse_options() and so will ignore even
standardised arguments such as "--help".

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-24 10:20:31 +01:00
Michael Brown 5b43181436 [efi] Support versions of shim that perform SBAT verification
The UEFI shim implements a fairly nicely designed revocation mechanism
designed around the concept of security generations.  Unfortunately
nobody in the shim community has thus far added the relevant metadata
to the Linux kernel, with the result that current versions of shim are
incapable of booting current versions of the Linux kernel.

Experience shows that there is unfortunately no point in trying to get
a fix for this upstreamed into shim.  We therefore default to working
around this undesirable behaviour by patching data read from the
"SbatLevel" variable used to hold SBAT configuration.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-23 15:27:20 +01:00
Michael Brown d2e1601cf4 [efi] Separate GetMemoryMap() wrapper from shim unlocker
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-23 14:52:30 +01:00
Michael Brown 95b8338f0d [efi] Add "shim" command
Allow a shim to be used to facilitate booting a kernel using a script
such as:

    kernel /images/vmlinuz console=ttyS0,115200n8
    initrd /images/initrd.img
    shim /images/shimx64.efi
    boot

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-22 15:37:11 +01:00
Michael Brown 28184b7c22 [efi] Add support for executing images via a shim
Add support for using a shim as a helper to execute an EFI image.
When a shim has been specified via shim(), the shim image will be
passed to LoadImage() instead of the selected EFI image and the
command line will be prepended with the name of the selected EFI
image.  The selected EFI image will be accessible to the shim via the
virtual filesystem as a hidden file.

Reduce the Secure Boot attack surface by removing, where possible, the
spurious requirement for a third party second stage loader binary such
as GRUB to be used solely in order to call the "shim lock protocol"
entry point.

Do not install the EFI PXE APIs when using a shim, since if shim finds
EFI_PXE_BASE_CODE_PROTOCOL on the loaded image's device handle then it
will attempt to download files afresh instead of using the files
already downloaded by iPXE and exposed via the EFI_SIMPLE_FILE_SYSTEM
protocol.  (Experience shows that there is no point in trying to get a
fix for this upstreamed into shim.)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-22 15:37:11 +01:00
Michael Brown 3c214f0465 [efi] Add definitions for the UEFI shim lock protocol
The UEFI shim includes a "shim lock protocol" that can be used by a
third party second stage loader such as GRUB to verify a kernel image.

Add definitions for the relevant portions of this protocol interface.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-22 15:37:11 +01:00
Michael Brown ce2200d5fb [efi] Add efi_asprintf() and efi_vasprintf()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-22 15:10:16 +01:00
Michael Brown c4a8d90387 [image] Generalise concept of selected image
Most image flags are independent values: any combination of flags may
be set for any image, and the flags for one image are independent of
the flags for any other image.  The "selected" flag does not follow
this pattern: at most one image may be marked as selected at any time.

When invoking a kernel via the UEFI shim, there will be multiple
"special" images: the selected kernel itself, the shim image, and
potentially a shim-signed GRUB binary to be used as a crutch to assist
shim in loading the kernel (since current versions of the UEFI shim
are not capable of directly loading a Linux kernel).

Remove the "selected" image flag and replace it with a general concept
of an image tag with the same semantics: a given tag may be assigned
to at most one image, an image may be found by its tag only while the
image is currently registered, and a tag will survive unregistration
and reregistration of an image (if it has not already been assigned to
a new image).  For visual consistency, also replace the current image
pointer with a current image tag.

The image pointer stored within the image tag holds only a weak
reference to the image, since the selection of an image should not
prevent that image from being freed.  (The strong reference to the
currently executing image is held locally within the execution scope
of image_exec(), and is logically separate from the current image
pointer.)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-17 14:42:03 +01:00
Michael Brown 79d85e29aa [efi] Attempt to detect EFI images that fail Secure Boot verification
An EFI image that is rejected by LoadImage() due to failing Secure
Boot verification is still an EFI image.  Unfortunately, the extremely
broken UEFI Secure Boot model provides no way for us to unambiguously
determine that a valid EFI executable image was rejected only because
it failed signature verification.  We must therefore use heuristics to
guess whether not an image that was rejected by LoadImage() could
still be loaded via a separate PE loader such as the UEFI shim.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-17 14:40:50 +01:00
Michael Brown 03eea19c19 [efi] Allow currently selected image to be opened as "grub*.efi"
Versions 15.4 and earlier of the UEFI shim are incapable of correctly
parsing the command line in order to extract the second stage loader
filename, and will always attempt to load "grubx64.efi" or equivalent.

Versions 15.3 and later of the UEFI shim are currently incapable of
loading a Linux kernel directly anyway, since the kernel does not
include SBAT metadata.  These versions will require a genuine
shim-signed GRUB binary to be used as a crutch to assist shim in
loading a Linux kernel.

This leaves versions 15.2 and earlier of the UEFI shim (as currently
used in e.g. RHEL7) as being capable of directly loading a Linux
kernel, but incorrectly attempting to load it using the filename
"grubx64.efi" or equivalent.  To support the bugs in these older
versions of the UEFI shim, allow the currently selected image to be
opened via any filename of the form "grub*.efi".

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-05 14:54:20 +01:00
Michael Brown 0bb0aea878 [efi] Allow currently executing image to be opened via virtual filesystem
When invoking a kernel via the UEFI shim, the kernel image must be
accessible via EFI_SIMPLE_FILE_SYSTEM_PROTOCOL but must not be present
in the magic initrd constructed from all registered images.

Re-register a currently executing EFI image and mark it as hidden,
thereby allowing it to be accessed via the virtual filesystem exposed
via EFI_SIMPLE_FILE_SYSTEM_PROTOCOL without appearing in the magic
initrd contents.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-05 14:54:20 +01:00
Michael Brown f9beb20e99 [image] Allow for images to be hidden from lists of all images
When invoking a kernel via the UEFI shim, the kernel (and potentially
also a helper binary such as GRUB) must be accessible via the virtual
filesystem exposed via EFI_SIMPLE_FILE_SYSTEM_PROTOCOL but must not be
present in the magic initrd constructed from all registered images.

Allow for images to be flagged as hidden, which will cause them to be
excluded from API-level lists of all images such as the virtual
filesystem directory contents, the magic initrd, or the Multiboot
module list.  Hidden images remain visible to iPXE commands including
"imgstat", which will show a "[HIDDEN]" flag for such images.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-05 14:54:20 +01:00
Michael Brown f93e6b712f [efi] Show original filenames in debug messages
Show the original filename as used by the consumer when calling our
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL's Open() method.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-05 13:05:28 +01:00
Michael Brown 22cc65535a [efi] Allow downloaded images to take precedence over constructed files
Try searching for a matching registered image before checking for
fixed filenames (such as "initrd.magic" for the dynamically generated
magic initrd file).  This minimises surprise by ensuring that an
explicitly downloaded image will always be used verbatim.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-05-05 13:05:28 +01:00
Michael Brown bd13697446 [efi] Allow for sections to be excluded from the generated PE file
Hybrid bzImage and UEFI binaries (such as wimboot) include a bzImage
header within a section starting at offset zero, with the PE header
effectively occupying unused space within this section.  This section
should not appear as a named section in the resulting PE file.

Allow for the existence of hidden sections that do not result in a
section header being written to the PE file.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-04-10 17:02:45 +01:00
Michael Brown 9fb28080d9 [efi] Allow elf2efi to be used for hybrid binaries
Hybrid 32-bit BIOS and 64-bit UEFI binaries (such as wimboot) may
include R_X86_64_32 relocation records for the 32-bit BIOS portions.
These should be ignored when generating PE relocation records, since
they apply only to code that cannot be executed within the context of
the 64-bit UEFI binary, and creating a 4-byte relocation record is
invalid in a binary that may be relocated anywhere within the 64-bit
address space (see commit 907cffb "[efi] Disallow R_X86_64_32
relocations").

Add a "--hybrid" option to elf2efi, which will cause R_X86_64_32
relocation records to be silently discarded.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-04-10 16:51:51 +01:00
Michael Brown 1e4c3789e9 [efi] Shrink size of data directory in PE header
Hybrid bzImage and UEFI binaries (such as wimboot) require the PE
header to be kept as small as possible, since the bzImage header
starts at a fixed offset 0x1f1.

The EFI_IMAGE_OPTIONAL_HEADER structures in PeImage.h define an
optional header containing 16 data directory entries, of which the
last eight are unused in binaries that we create.  Shrink the data
directory to contain only the first eight entries, to minimise the
overall size of the PE header.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-04-10 16:51:49 +01:00
Michael Brown 0d04635ef0 [efi] Remove redundant zero padding in PE header
Hybrid bzImage and UEFI binaries (such as wimboot) require the PE
header to be kept as small as possible, since the bzImage header
starts at a fixed offset 0x1f1.

The PE header currently includes 128 bytes of zero padding between the
DOS and NT header portions.  This padding has been present since
commit 81d92c6 ("[efi] Add EFI image format and basic runtime
environment") first added support for EFI images in iPXE, and was
included on the basis of matching the observed behaviour of the
Microsoft toolchain.  There appears to be no requirement for this
padding to exist: EDK2 binaries built with gcc include only 64 bytes
of zero padding, Linux kernel binaries include 66 bytes of non-zero
padding, and wimboot binaries include no padding at all.

Remove the unnecessary padding between the DOS and NT header portions
to minimise the overall size of the PE header.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-04-10 16:50:10 +01:00
Michael Brown 1d1cf74a5e [tls] Handle fragmented handshake records
Originally-implemented-by: Christopher Schenk <christopher@cschenk.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-30 23:38:43 +01:00
Michael Brown aa368ba529 [tls] Pass I/O buffer to received record handlers
Prepare for the possibility that a record handler may choose not to
consume the entire record by passing the I/O buffer and requiring the
handler to mark consumed data using iob_pull().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-30 23:37:55 +01:00
Michael Brown 2c6a15d2a3 [tls] Clean up change cipher spec record handling
Define and use data structures and constants for the (single-byte)
change cipher spec records.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-30 16:57:12 +01:00
Michael Brown 09e8a15408 [efi] Claim fixed device paths by uninstalling device path protocol
As documented in commits 6a004be ("[efi] Support the initrd
autodetection mechanism in newer Linux kernels") and 04e60a2 ("[efi]
Omit EFI_LOAD_FILE2_PROTOCOL for a zero-length initrd"), the choice in
Linux of using a fixed device path requires bootloaders to allow for
the fact that a previous bootloader may have already installed a
handle with the fixed device path.

We currently deal with this situation by reusing the existing handle,
replacing the EFI_LOAD_FILE2_PROTOCOL instance with our own.  Simplify
the code by instead uninstalling the EFI_DEVICE_PATH_PROTOCOL instance
from the existing handle (if present), thereby allowing the creation
of a new handle to succeed.

Create the new handle only if we have a non-empty initrd to provide.
This works around bugs in bootloaders such as the systemd EFI stub
that fail to allow for the existence of multiple-bootloader chains.
(The workaround is not comprehensive: if the user has downloaded other
images in iPXE before invoking the systemd Unified Kernel Image (UKI),
then the systemd EFI stub will still crash and burn since it fails to
allow for the fact that a previous bootloader has already installed a
handle with the fixed device path.)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-15 16:48:35 +00:00
Matt Parrella bf25e23d07 [intel] Add workaround for I210 reset hardware bugs
The Intel I210's packet buffer size registers reset only on power up,
not when a reset signal is asserted.  This can lead to the inability
to pass traffic in the event that the DMA TX Maximum Packet Size
(which does reset to its default value on reset) is bigger than the TX
Packet Buffer Size.

For example, an operating system may be using the time sensitive
networking features of the I210 and the registers may be programmed
correctly, but then a reset signal is asserted and iPXE on the next
boot will be unable to use the I210.

Mimic what Linux does and forcibly set the registers to their default
values.

Signed-off-by: Matt Parrella <parrella.matthew@gmail.com>
2023-03-14 14:44:32 +00:00
Michael Brown 8f1c120119 [dhcp] Unregister ProxyDHCP and PXEBS settings on a successful DHCPACK
When a DHCP transaction does not result in the registration of a new
"proxydhcp" or "pxebs" settings block, any existing settings blocks
are currently left unaltered.

This can cause surprising behaviour.  For example: when chainloading
iPXE, the "proxydhcp" and "pxebs" settings blocks may be prepopulated
using cached values from the previous PXE bootloader.  If iPXE
performs a subsequent DHCP request, then the DHCP or ProxyDHCP servers
may choose to respond differently to iPXE.  The response may choose to
omit the ProxyDHCP or PXEBS stages, in which case no new "proxydhcp"
or "pxebs" settings blocks may be registered.  This will result in
iPXE using a combination of both old and new DHCP responses.

Fix by assuming that a successful DHCPACK effectively acquires
ownership of the "proxydhcp" and "pxebs" settings blocks, and that any
existing settings blocks should therefore be unregistered.

Reported-by: Henry Tung <htung@palantir.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-14 11:35:30 +00:00
Michael Brown 54fcb7c29c [efi] Use image name instead of pointer value in debug messages
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-07 14:18:00 +00:00
Michael Brown 9e1f7a3659 [image] Always unregister currently executing image
We unregister script images during their execution, to prevent a
"boot" command from re-executing the containing script.  This also has
the side effect of preventing executing scripts from showing up within
the Linux magic initrd image (or the Multiboot module list).

Additional logic in bzimage.c and efi_file.c prevents a currently
executing kernel from showing up within the magic initrd image.
Similar logic in multiboot.c prevents the Multiboot kernel from
showing up as a Multiboot module.

This still leaves some corner cases that are not covered correctly.
For example: when using a gzip-compressed kernel image, nothing will
currently hide the original compressed image from the magic initrd.

Fix by moving the logic that temporarily unregisters the current image
from script_exec() to image_exec(), so that it applies to all image
types, and simplify the magic initrd and Multiboot module list
construction logic on the basis that no further filtering of the
registered image list is necessary.

This change has the side effect of hiding currently executing EFI
images from the virtual filesystem exposed by iPXE.  For example, when
using iPXE to boot wimboot, the wimboot binary itself will no longer
be visible within the virtual filesystem.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-07 12:22:19 +00:00
Michael Brown e51e7bbad7 [image] Consistently use for_each_image() to iterate over images
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-06 16:56:37 +00:00
Forest Crossman 523788ccda [intelx] Add PCI IDs for Intel 82599 10GBASE-T NIC
Signed-off-by: Forest Crossman <cyrozap@gmail.com>
2023-03-05 18:22:18 -06:00
Michael Brown 96bb6ba441 [params] Allow for arbitrary HTTP request headers to be specified
Extend the request parameter mechanism to allow for arbitrary HTTP
headers to be specified via e.g.:

  params
  param --header Referer http://www.example.com
  imgfetch http://192.168.0.1/script.ipxe##params

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-01 12:20:02 +00:00
Michael Brown 33cb56cf1b [params] Rename "form parameter" to "request parameter"
Prepare for the parameter mechanism to be generalised to specifying
request parameters that are passed via mechanisms other than an
application/x-www-form-urlencoded form.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-01 11:55:04 +00:00
Michael Brown 60531ff6e2 [http] Use POST method only if the form parameter list is non-empty
An attempt to use an existent but empty form parameter list will
currently result in an invalid POST request since the Content-Length
header will be missing.

Fix by using GET instead of POST if the form parameter list is empty.
This is a non-breaking change (since the current behaviour produces an
invalid request), and simplifies the imminent generalisation of the
parameter list concept to handle both header and form parameters.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-03-01 11:12:44 +00:00
Michael Brown 04e60a278a [efi] Omit EFI_LOAD_FILE2_PROTOCOL for a zero-length initrd
When the Linux kernel is being used with no initrd, iPXE will still
provide a zero-length initrd.magic file within the virtual filesystem.
As of commit 6a004be ("[efi] Support the initrd autodetection
mechanism in newer Linux kernels"), this zero-length file will also be
exposed via an EFI_LOAD_FILE2_PROTOCOL instance on a handle with a
fixed device path.

The correct handling of zero-length files via EFI_LOAD_FILE2_PROTOCOL
is unfortunately not well defined.

Linux expects the first call to LoadFile() to always fail with
EFI_BUFFER_TOO_SMALL.  When the initrd is genuinely zero-length, iPXE
will return success since the buffer is not too small to hold the
(zero-length) file.  This causes Linux to immediately report a
spurious EFI_LOAD_ERROR boot failure.

We could change the logic in iPXE's efi_file_load() to always return
EFI_BUFFER_TOO_SMALL if Buffer is NULL on entry.  Since the correct
behaviour of LoadFile() in the corner case of a zero-length file is
left undefined by the UEFI specification, this would be permissible.

Unfortunately this approach would not fix the problem.  If we return
EFI_BUFFER_TOO_SMALL and set the file length to zero, then Linux will
call the boot services AllocatePages() method with a zero length.  In
at least the EDK2 implementation, this combination of parameters will
cause AllocatePages() to return EFI_OUT_OF_RESOURCES, and Linux will
again report a boot failure.

Another approach would be to install the initrd device path handle
only if we have a non-empty initrd to offer.  Unfortunately this would
lead to a failure in yet another corner case: if a previous bootloader
has installed an initrd device path handle (e.g. to pass a boot script
to iPXE) then we must not leave that initrd in place, since then our
loaded kernel would end up seeing the wrong initrd content.

The cleanest fix seems to be to ensure that the initrd device path
handle is installed with the EFI_DEVICE_PATH_PROTOCOL instance present
but with the EFI_LOAD_FILE2_PROTOCOL instance absent (and forcibly
uninstalled if necessary), matching the state in which we leave the
handle after uninstalling our virtual filesystem.  Linux will then not
find any handle that supports EFI_LOAD_FILE2_PROTOCOL within the fixed
device path, and so will fall through to trying other mechanisms to
locate the initrd.

Reported-by: Chris Bradshaw <cwbshaw@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-28 12:30:54 +00:00
Michael Brown 471599dc77 [efi] Split out EFI_RNG_PROTOCOL as a separate entropy source
Commit 7ca801d ("[efi] Use the EFI_RNG_PROTOCOL as an entropy source
if available") added EFI_RNG_PROTOCOL as an alternative entropy source
via an ad-hoc mechanism specific to efi_entropy.c.

Split out EFI_RNG_PROTOCOL to a separate entropy source, and allow the
entropy core to handle the selection of RDRAND, EFI_RNG_PROTOCOL, or
timer ticks as the active source.

The fault detection logic added in commit a87537d ("[efi] Detect and
disable seriously broken EFI_RNG_PROTOCOL implementations") may be
removed completely, since the failure will already be detected by the
generic ANS X9.82-mandated repetition count test and will now be
handled gracefully by the entropy core.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-20 14:53:10 +00:00
Michael Brown 7d71cf318a [rng] Allow for entropy sources that fail during startup tests
Provide per-source state variables for the repetition count test and
adaptive proportion test, to allow for the situation in which an
entropy source can be enabled but then fails during the startup tests,
thereby requiring an alternative entropy source to be used.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-20 14:53:10 +00:00
Michael Brown 6625e49cea [tables] Allow any lvalue to be used as a table iterator
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-20 13:46:45 +00:00
Michael Brown 9f17d1116d [rng] Allow entropy source to be selected at runtime
As noted in commit 3c83843 ("[rng] Check for several functioning RTC
interrupts"), experimentation shows that Hyper-V cannot be trusted to
reliably generate RTC interrupts.  (As noted in commit f3ba0fb
("[hyperv] Provide timer based on the 10MHz time reference count
MSR"), Hyper-V appears to suffer from a general problem in reliably
generating any legacy interrupts.)  An alternative entropy source is
therefore required for an image that may be used in a Hyper-V Gen1
virtual machine.

The x86 RDRAND instruction provides a suitable alternative entropy
source, but may not be supported by all CPUs.  We must therefore allow
for multiple entropy sources to be compiled in, with the single active
entropy source selected only at runtime.

Restructure the internal entropy API to allow a working entropy source
to be detected and chosen at runtime.

Enable the RDRAND entropy source for all x86 builds, since it is
likely to be substantially faster than any other source.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-17 21:29:51 +00:00
Michael Brown 2733c4763a [iscsi] Limit maximum transfer size to MaxBurstLength
We currently specify only the iSCSI default value for MaxBurstLength
and ignore any negotiated value, since our internal block device API
allows only for receiving directly into caller-allocated buffers and
so we have no intrinsic limit on burst length.

A conscientious target may however refuse to attempt a transfer that
we request for a number of blocks that would exceed the negotiated
maximum burst length.

Fix by recording the negotiated maximum burst length and using it to
limit the maximum number of blocks per transfer as reported by the
SCSI layer.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-16 13:27:25 +00:00
Michael Brown cff857461b [rng] Add RDRAND as an entropy source
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-15 22:43:33 +00:00
Michael Brown 6a004be0cc [efi] Support the initrd autodetection mechanism in newer Linux kernels
Linux 5.7 added the ability to autodetect an initrd by searching for a
handle via a fixed vendor-specific "Linux initrd device path" and then
locating and using the EFI_LOAD_FILE2_PROTOCOL instance on that
handle.

This maps quite naturally onto our existing concept of a "magic
initrd" as introduced for EFI in commit e5f0255 ("[efi] Provide an
"initrd.magic" file for use by UEFI kernels").

Add an EFI_LOAD_FILE2_PROTOCOL instance to our EFI virtual files
(backed by simply calling the existing EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
method to read from the file), and install the protocol instance for
the "initrd.magic" virtual file onto a new device handle that also
provides the Linux initrd device path.

The design choice in Linux of using a single fixed device path makes
this unfortunately messy to support, since device paths must be unique
within a system.  When multiple bootloaders are used (e.g. GRUB
loading iPXE loading Linux) then only one bootloader can ever install
the device path onto a handle.  Subsequent bootloaders must locate the
existing handle and replace the load file protocol instance with their
own.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-15 17:36:47 +00:00
Michael Brown cf9ad00afc [efi] Fix debug message when reading from EFI virtual files
Show the requested range when a caller reads from a virtual file via
the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL interface.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-15 17:20:39 +00:00
Michael Brown 76a286530a [image] Check delimiters when parsing command-line key-value arguments
The Linux kernel bzImage image format and the CPIO archive constructor
will parse the image command line for certain arguments of the form
"key=value".  This parsing is currently implemented using strstr() in
a way that can cause a false positive suffix match.  For example, a
command line containing "highmem=<n>" would erroneously be treated as
containing a value for "mem=<n>".

Fix by centralising the logic used for parsing such arguments, and
including a check that the argument immediately follows a whitespace
delimiter (or is at the start of the string).

Reported-by: Filippo Giunchedi <filippo@esaurito.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-14 11:13:45 +00:00
Michael Brown 3c83843e11 [rng] Check for several functioning RTC interrupts
Commit 74222cd ("[rng] Check for functioning RTC interrupt") added a
check that the RTC is capable of generating interrupts via the legacy
PIC, since this mechanism appears to be broken in some Hyper-V virtual
machines.

Experimentation shows that the RTC is sometimes capable of generating
a single interrupt, but will then generate no subsequent interrupts.
This currently causes rtc_entropy_check() to falsely detect that the
entropy gathering mechanism is functional.

Fix by checking for several RTC interrupts before declaring that it is
a functional entropy source.

Reported-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-11 15:11:51 +00:00
Michael Brown be8ecaf805 [eisa] Check for system board presence before probing for slots
EISA expansion slot I/O port addresses overlap space that may be
assigned to PCI devices, which can lead to register reads and writes
with unwanted side effects during EISA probing.

Reduce the chances of performing EISA probing on PCI devices by
probing EISA slot vendor and product ID registers only if the EISA
system board vendor ID register indicates that the motherboard
supports EISA.

Debugged-by: Václav Ovsík <vaclav.ovsik@gmail.com>
Tested-by: Václav Ovsík <vaclav.ovsik@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-10 23:34:59 +00:00
Xiaotian Wu 62a1d5c0f5 [loong64] Add initial support for LoongArch64
Add support for building a LoongArch64 Linux userspace binary.

Signed-off-by: Xiaotian Wu <wuxiaotian@loongson.cn>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-06 21:14:17 +00:00
Michael Brown 84cb774390 [test] Include build architecture in test suite banner
The test suites for the various architectures are often run back to
back, and there is currently nothing to visually distinguish one test
run from another.

Include the architecture name within the self-test startup banner, to
aid in visual identification of test results.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-06 21:06:00 +00:00
Michael Brown ef0a6f4792 [ioapi] Move PAGE_SHIFT to bits/io.h
The PAGE_SHIFT definition is an architectural property, rather than an
aspect of a particular I/O API implementation (of which, in theory,
there may be more than one per architecture).

Reflect this by moving the definition to the top-level bits/io.h for
each architecture.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-06 12:34:21 +00:00
Michael Brown c6901792f0 [build] Allow for per-architecture unprefixed constant operand modifier
Over the years, the undocumented operand modifier used to produce the
unprefixed constant values in __einfo_error() has varied from "%c0" to
"%a0" in commit 1a77466 ("[build] Fix use of inline assembly on GCC
4.8 ARM64 builds") and back to "%c0" in commit 3fb3ffc ("[build] Fix
use of inline assembly on GCC 8 ARM64 builds"), according to the
evolving demands of the toolchain.

LoongArch64 suffers from a similar issue: GCC 13 will allow either,
but the currently released GCC 12 allows only the "%a0" form.

Introduce a macro ASM_NO_PREFIX, defined in bits/compiler.h, to
abstract away this difference and allow different architectures to use
different operand modifiers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-05 23:55:14 +00:00
Michael Brown a2bed43939 [xen] Allow for platforms that have no Xen support
The Xen headers support only x86 and ARM.  Allow for platforms such as
LoongArch64 to build despite the absence of Xen support by providing
an architecture-specific <bits/xen.h> that simply does:

  #ifndef _BITS_XEN_H
  #define _BITS_XEN_H
  #include <ipxe/nonxen.h>
  #endif /* _BITS_XEN_H */

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-05 22:21:36 +00:00
Michael Brown 7cc305f7b4 [efi] Enable NET_PROTO_LLDP by default
Requested-by: Christian I. Nilsson <nikize@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-05 18:54:39 +00:00
Michael Brown dc16de3204 [lldp] Add support for the Link Layer Discovery Protocol
Add support for recording LLDP packets and exposing TLV values via the
settings mechanism.  LLDP settings are encoded as

  ${netX.lldp/<prefix>.<type>.<index>.<offset>.<length>}

where

  <type> is the TLV type

  <offset> is the starting offset within the TLV value

  <length> is the length (or zero to read the from <offset> to the end)

  <prefix>, if it has a non-zero value, is the subtype byte string of
  length <offset> to match at the start of the TLV value, up to a
  maximum matched length of 4 bytes

  <index> is the index of the entry matching <type> and <prefix> to be
  accessed, with zero indicating the first matching entry

The <prefix> is designed to accommodate both matching of the OUI
within an organization-specific TLV (e.g. 0x0080c2 for IEEE 802.1
TLVs) and of a subtype byte as found within many TLVs.

This encoding allows most LLDP values to be extracted easily.  For
example

  System name: ${netX.lldp/5.0.0.0:string}

  System description: ${netX.lldp/6.0.0.0:string}

  Port description: ${netX.lldp/4.0.0.0:string}

  Port interface name: ${netX.lldp/5.2.0.1.0:string}

  Chassis MAC address: ${netX.lldp/4.1.0.1.0:hex}

  Management IPv4 address: ${netX.lldp/5.1.8.0.2.4:ipv4}

  Port VLAN ID: ${netX.lldp/0x0080c2.1.127.0.4.2:int16}

  Port VLAN name: ${netX.lldp/0x0080c2.3.127.0.7.0:string}

  Maximum frame size: ${netX.lldp/0x00120f.4.127.0.4.2:uint16}

Originally-implemented-by: Marin Hannache <git@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-05 18:18:02 +00:00
Michael Brown 8450fa4a7b [dhcp] Ignore DHCPNAK unless originating from the selected DHCP server
RFC 2131 leaves undefined the behaviour of the client in response to a
DHCPNAK that comes from a server other than the selected DHCP server.

A substantial amount of online documentation suggests using multiple
independent DHCP servers with non-overlapping ranges in the same
subnet in order to provide some minimal redundancy.  Experimentation
shows that in this setup, at least ISC dhcpd will send a DHCPNAK in
response to the client's DHCPREQUEST for an address that is not within
the range defined on that server.  (Since the requested address does
lie within the subnet defined on that server, this will happen
regardless of the "authoritative" parameter.)  The client will
therefore receive a DHCPACK from the selected DHCP server along with
one or more DHCPNAKs from each of the non-selected DHCP servers.

Filter out responses from non-selected DHCP servers before checking
for a DHCPNAK, so that these arguably spurious DHCPNAKs will not cause
iPXE to return to the discovery state.

Continue to check for DHCPNAK before filtering out responses for
non-selected lease addresses, since experimentation shows that the
DHCPNAK will usually have an empty yiaddr field.

Reported-by: Anders Blomdell <anders.blomdell@control.lth.se>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-03 19:51:58 +00:00
Michael Brown 4e456d9928 [efi] Do not attempt to drive PCI bridge devices
The "bridge" driver introduced in 3aa6b79 ("[pci] Add minimal PCI
bridge driver") is required only for BIOS builds using the ENA driver,
where experimentation shows that we cannot rely on the BIOS to fully
assign MMIO addresses.

Since the driver is a valid PCI driver, it will end up binding to all
PCI bridge devices even on a UEFI platform, where the firmware is
likely to have completed MMIO address assignment correctly.  This has
no impact on most systems since there is generally no UEFI driver for
PCI bridges: the enumeration of the whole PCI bus is handled by the
PciBusDxe driver bound to the root bridge.

Experimentation shows that at least one laptop will freeze at the
point that iPXE attempts to bind to the bridge device.  No deeper
investigation has been carried out to find the root cause.

Fix by causing efipci_supported() to return an error unless the
configuration space header type indicates a non-bridge device.

Reported-by: Marcel Petersen <mp@sbe.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-03 16:10:31 +00:00
Xiaotian Wu d405a0bd84 [util] Add support for LoongArch64 binaries
Signed-off-by: Xiaotian Wu <wuxiaotian@loongson.cn>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-03 12:44:11 +00:00
Michael Brown 8b645eea16 [xen] Update to current Xen headers
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-02 11:19:44 +00:00
Michael Brown 6f250be279 [efi] Allow autoexec script to be located alongside iPXE binary
Try loading the autoexec.ipxe script first from the directory
containing the iPXE binary (based on the relative file path provided
to us via EFI_LOADED_IMAGE_PROTOCOL), then fall back to trying the
root directory.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-01 23:54:19 +00:00
Michael Brown b6304f2984 [realtek] Explicitly disable VLAN offload
Some cards seem to have the receive VLAN tag stripping feature enabled
by default, which causes received VLAN packets to be misinterpreted as
being received by the trunk device.

Fix by disabling VLAN tag stripping in the C+ Command Register.

Debugged-by: Xinming Lai <yiyihu@gmail.com>
Tested-by: Xinming Lai <yiyihu@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-01 19:09:30 +00:00
Michael Brown aa85c2918a [efi] Update to current EDK2 headers
Update to pick up the upstream commit bda715b ("MdePkg: Fix UINT64 and
INT64 word length for LoongArch64").

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-02-01 10:50:47 +00:00
Michael Brown 66a2ff442d [tests] Verify ability to sleep the CPU
The self-test suite does not currently ever attempt to sleep the CPU.
This is an operation that may fail (e.g. by attempting to execute a
privileged instruction while running as a Linux userspace binary, or
by halting the CPU with all interrupts disabled).

Add a trivial self-test to exercise the ability to sleep the CPU
without crashing or halting forever.

Inspired-by: Xiaotian Wu <wuxiaotian@loongson.cn>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-31 10:17:57 +00:00
Michael Brown 3bcd0d3271 [dhcp] Add IANA-defined values for all current EFI client architectures
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-31 02:00:12 +00:00
Michael Brown 4bb521a8c4 [efi] Accept a command line passed to an iPXE image via LoadOptions
Treat a command line passed to iPXE via UEFI LoadOptions as an image
to be registered at startup, as is already done for the .lkrn, .pxe,
and .exe BIOS images.

Originally-implemented-by: Ladi Prosek <lprosek@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-29 18:56:11 +00:00
Michael Brown b9be454010 [la64] Import LoongArch64 ProcessorBind.h from EDK2 headers
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-28 19:14:00 +00:00
Michael Brown e3d543437e [efi] Update to current EDK2 headers
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-28 17:22:25 +00:00
Michael Brown 137ca5d877 [efi] Mark ConsoleControl.h as a non-imported header
The obsolete ConsoleControl.h header is no longer present in the
current EDK2 codebase, but is still required for interoperability with
old iMacs.

Add an iPXE include guard to this file so that the EDK2 header import
script will no longer attempt to import it from the EDK2 tree.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-28 17:22:25 +00:00
Michael Brown 900379594a [efi] Remove deleted directories from EDK2 header import script
The IntelFrameworkPkg and EdkCompatibilityPkg directories have been
removed from the EDK2 codebase.  Remove these directories from the
EDK2 header import script.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-28 17:22:25 +00:00
Michael Brown 91944c6341 [efi] Allow for whitespace before #include in imported EDK2 header files
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-28 17:22:25 +00:00
Michael Brown dac41fc4ec [efi] Detect SPDX licence identifiers in imported EDK2 headers
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-28 17:22:25 +00:00
Michael Brown 5220bdc524 [legal] Add missing FILE_LICENCE declaration to efi_path.c
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-28 17:15:16 +00:00
Michael Brown 38f54fb413 [legal] Add support for the BSD-2-Clause-Patent licence
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-28 17:07:40 +00:00
Michael Brown 5bf8b11527 [efi] Build util/efirom as a host-only binary
As with util/elf2efi32 and util/elf2efi64 in commit a99e435 ("[efi] Do
not rely on ProcessorBind.h when building host binaries"), build
util/efirom without using any architecture-specific EDK2 headers since
the build host's CPU architecture may not be supported by EDK2.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-28 16:26:28 +00:00
Michael Brown 2d180ce233 [tcp] Update maximum window size to 2MB
The current maximum window size of 256kB was calculated based on rough
link bandwidth and RTT measurements taken in 2012, and is too small to
avoid filling the TCP window on some modern links.

Update the list of typical link bandwidth and RTT figures to reflect
the modern world, and increase the maximum window size accordingly.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-25 18:34:01 +00:00
Michael Brown 4bffe0f0d9 [pxe] Discard queued PXE UDP packets when under memory pressure
The PXE UDP receive queue may grow without limit if the PXE NBP does
not call PXENV_UDP_READ sufficiently frequently.

Fix by implementing a cache discarder for received PXE UDP packets
(similar to the TCP cache discarder).

Reported-by: Tal Shorer <shorer@amazon.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-25 10:03:09 +00:00
Mohammed Taha c5426cdaa9 [golan] Add new PCI ID for NVIDIA BlueField-3 network device
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 22:52:30 +00:00
Michael Brown e72670ad7b [pxe] Avoid drawing menu items on bottom row of screen
Many consoles will scroll immediately upon drawing a character in the
rightmost column of the bottom row of the display, in order to be able
to advance the cursor to the next character (even if the cursor is
disabled).

This causes PXE menus to display incorrectly.  Specifically, pressing
the down arrow key while already on the last menu item may cause the
whole screen to scroll and the line to be duplicated.

Fix by moving the PXE menu one row up from the bottom of the screen.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 20:30:59 +00:00
Michael Brown 68734b9a4d [efi] Bind to only the topmost instance of the SNP or NII protocols
UEFI has the mildly annoying habit of installing copies of the
EFI_SIMPLE_NETWORK_PROTOCOL instance on the IPv4 and IPv6 child device
handles.  This can cause iPXE's SNP driver to attempt to bind to a
copy of the EFI_SIMPLE_NETWORK_PROTOCOL that iPXE itself provided on a
different handle.

Fix by refusing to bind to an SNP (or NII) handle if there exists
another instance of the same protocol further up the device path (on
the basis that we always want to bind to the highest possible device).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 19:27:13 +00:00
Michael Brown 2fef0c541e [efi] Extend efi_locate_device() to allow searching up the device path
Extend the functionality of efi_locate_device() to allow callers to
find instances of the protocol that may exist further up the device
path.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 19:27:13 +00:00
Michael Brown 1cd0a248cc [efi] Add efi_path_prev() utility function
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 19:27:13 +00:00
Michael Brown 204d39222a [efi] Add efi_path_terminate() utility function
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 19:27:11 +00:00
Michael Brown fcfb70bfb2 [arm] Inhibit linker warnings about an implied executable stack
Some versions of the 32-bit ARM linker seem to treat the absence of a
.note.GNU-stack section as implying an executable stack, and will
print a warning that this is deprecated behaviour.

Silence the warning by adding a .note.GNU-stack section to each
assembly file and retaining the sections in the Linux linker script.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 12:55:44 +00:00
Michael Brown c5e1f007ac [arm] Use -mfloat-abi=soft only for EFI builds
The EFI ABI requires the use of -mfloat-abi=soft, but other platforms
may require -mfloat-abi=hard.

Allow for this by using -mfloat-abi=soft only for EFI builds.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 01:32:14 +00:00
Michael Brown 9de6c45dd3 [arm] Use -fno-short-enums for all 32-bit ARM builds
The EFI ABI requires the use of -fno-short-enums, and the EDK2 headers
will perform a compile-time check that enums are 32 bits.

The EDK2 headers may be included even in builds for non-EFI platforms,
and so the -fno-short-enums flag must be used in all 32-bit ARM
builds.  Fortunately, nothing else currently cares about enum sizes.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-23 01:26:46 +00:00
Michael Brown 8f59911b20 [arm] Support building as a Linux userspace binary for AArch64
Add support for building as a Linux userspace binary for AArch64.
This allows the self-test suite to be more easily run for the 64-bit
ARM code.  For example:

  # On a native AArch64 system:
  #
  make bin-arm64-efi/tests.linux && ./bin-arm64-efi/tests.linux

  # On a non-AArch64 system (e.g. x86_64) via cross-compilation,
  # assuming that kernel and glibc headers are present within
  # /usr/aarch64-linux-gnu/sys-root/:
  #
  make bin-arm64-linux/tests.linux CROSS=aarch64-linux-gnu- && \
  qemu-aarch64 -L /usr/aarch64-linux-gnu/sys-root/ \
               ./bin-arm64-linux/tests.linux

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-22 20:36:57 +00:00
Michael Brown 2061d658b3 [dhcp] Simplify platform-specific client architecture definitions
Move the platform-specific DHCP client architecture definitions to
header files of the form <ipxe/$(PLATFORM)/dhcparch.h>.  This
simplifies the directory structure and allows the otherwise unused
arch/$(ARCH)/include/$(PLATFORM) to be removed from the include
directory search path, which avoids the confusing situation in which a
header file may potentially be accessed through more than one path.

For Linux userspace binaries on any architecture, use the EFI values
for that architecture by delegating to the EFI header file.  This
avoids the need to explicitly select values for Linux userspace
binaries for each architecture.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-22 17:45:34 +00:00
Michael Brown 2ef5f5e05e [build] Move -Ulinux to common Makefile
The requirement to undo the implicit "-Dlinux" is not specific to the
x86 architecture.  Move this out of the x86-specific Makefile.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2023-01-22 16:19:22 +00:00