ipxe:vbox

Last commit made on 2023-06-27
Get this branch:
git clone -b vbox https://git.launchpad.net/ipxe

Branch merges

Branch information

Name:
vbox
Repository:
lp:ipxe

Recent commits

22916e6... by Michael Brown <email address hidden>

WIP

570134c... by Michael Brown <email address hidden>

[efi] Rename "driver" to "target" in preparation for two-phase veto mechanism

Forcible uninstallation of handles installed by a vetoed driver can be
done only on the basis of an image handle, since there is no way
within the UEFI driver model to identify the driver that installed a
protocol on a handle. A single image may provide multiple drivers.

This will require a two-phase mechanism in which we first perform the
DisconnectController() calls, uninstall the driver binding protocols,
and close any stray handles associated with the driver handle. Once
all driver binding handles have been processed in this way, a second
pass can close and uninstall any stray handles associated with the
image handle.

Prepare for a two-phase veto mechanism by renaming the "driver" handle
to a "target" handle (which may be either the driver handle or the
image handle).

Signed-off-by: Michael Brown <email address hidden>

a029f4e... by Michael Brown <email address hidden>

[efi] Veto the VirtualBox E1kNetDxe driver

The VirtualBox E1kNetDxe driver has a Stop() method that relies on
being passed its own child device handle. Unfortunately, the same
driver's Start() method never opens the parent device handle with
BY_CHILD_CONTROLLER attributes on behalf of the newly installed child
device handle, with the result that the UEFI device model is
completely unaware of the nominal parent-child relationship. This
omission can be observed via the UEFI shell "devtree" command, which
will show the child SNP device handle as a standalone top-level device
handle, with no relationship to its underlying parent PCI device
handle.

The upshot of this omission is that the VirtualBox E1kNetDxe driver's
Stop() method is a pure no-op. Calling DisconnectController() on the
PCI device handle will return successfully, but will not have actually
disconnected anything. A subsequent attempt to open the handle on
behalf of iPXE's native Intel driver will get stuck in an infinite
loop inside OpenProtocol(), as the firmware repeatedly calls
DisconnectController() in an attempt to disconnect the E1kNetDxe
driver from the PCI device handle.

Work around this problem by adding the buggy VirtualBox E1kNetDxe
driver to the veto list.

Signed-off-by: Michael Brown <email address hidden>

ae435cb... by Michael Brown <email address hidden>

[efi] Process veto objects in reverse order of enumeration

While not guaranteed by the UEFI specification, the enumeration of
handles, protocols, and openers will generally return results in order
of creation. Processing these objects in reverse order (as is already
done when calling DisconnectController() on the list of all handles)
will generally therefore perform the forcible uninstallation
operations in reverse order of object creation, which minimises the
number of implicit operations performed (e.g. when disconnecting a
controller that itself still has existent child controllers).

Signed-off-by: Michael Brown <email address hidden>

f8a0d1c... by Michael Brown <email address hidden>

[efi] Check for protocols opened by vetoed driver and image handles

The UEFI specification states that the AgentHandle may be either the
driving binding protocol handle or the image handle.

Check for both handles when searching for stale handles to be forcibly
closed on behalf of a vetoed driver.

Signed-off-by: Michael Brown <email address hidden>

f0b1025... by Michael Brown <email address hidden>

[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 <email address hidden>

c832580... by Michael Brown <email address hidden>

[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 <email address hidden>

9a11832... by Michael Brown <email address hidden>

[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 <email address hidden>

2689a6e... by Michael Brown <email address hidden>

[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 <email address hidden>

4fa4052... by Michael Brown <email address hidden>

[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 <email address hidden>