Compare commits

..

1 Commits

Author SHA1 Message Date
eff6a07aa2 [xhci] Avoid DMA during shutdown if firmware has disabled bus mastering
On some systems (observed with the Thunderbolt ports on a ThinkPad X1
Extreme Gen3 and a ThinkPad P53), the system firmware will disable bus
mastering on the xHCI controller and all PCI bridges at the point that
ExitBootServices() is called if the IOMMU is enabled.  This leaves the
xHCI controller unable to shut down cleanly since all commands will
fail with a timeout.

Commit 85eb961 ("[xhci] Allow for permanent failure of the command
mechanism") allows us to detect that this has happened and respond
cleanly.  However, some unidentified hardware component (either the
xHCI controller or one of the PCI bridges) seems to manage to enqueue
the attempted DMA operation and eventually complete it after the
operating system kernel has reenabled bus mastering.  This results in
a DMA operation to an area of memory that the hardware is no longer
permitted to access.  On Windows with the Driver Verifier enabled,
this will result in a STOP 0xE6 (DRIVER_VERIFIER_DMA_VIOLATION).

Work around this problem by detecting when bus mastering has been
disabled, and immediately failing the device to avoid initiating any
further DMA attempts.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2021-11-12 15:57:51 +00:00
34 changed files with 100 additions and 365 deletions

View File

@ -190,7 +190,7 @@ vmware : bin/8086100f.mrom bin/808610d3.mrom bin/10222000.rom bin/15ad07b0.rom
@$(ECHO) ' bin/10222000.rom -- vlance/pcnet32'
@$(ECHO) ' bin/15ad07b0.rom -- vmxnet3'
@$(ECHO)
@$(ECHO) 'For more information, see https://ipxe.org/howto/vmware'
@$(ECHO) 'For more information, see http://ipxe.org/howto/vmware'
@$(ECHO)
@$(ECHO) '==========================================================='

View File

@ -918,7 +918,7 @@ $(BIN)/deps/%.d : % $(MAKEDEPS)
# Calculate list of dependency files
#
AUTO_DEPS = $(patsubst %,$(BIN)/deps/%.d,$(AUTO_SRCS) core/version.c)
AUTO_DEPS = $(patsubst %,$(BIN)/deps/%.d,$(AUTO_SRCS))
autodeps :
@$(ECHO) $(AUTO_DEPS)
VERYCLEANUP += $(BIN)/deps
@ -1202,7 +1202,7 @@ endif
# Build version
#
GIT_INDEX := $(if $(GITVERSION),$(if $(wildcard ../.git/index),../.git/index))
$(BIN)/version.%.o : core/version.c $(MAKEDEPS) $(version_DEPS) $(GIT_INDEX)
$(BIN)/version.%.o : core/version.c $(MAKEDEPS) $(GIT_INDEX)
$(QM)$(ECHO) " [VERSION] $@"
$(Q)$(COMPILE_c) -DBUILD_NAME="\"$*\"" \
-DVERSION_MAJOR=$(VERSION_MAJOR) \

View File

@ -136,8 +136,6 @@ SECTIONS {
*(.note.*)
*(.discard)
*(.discard.*)
*(.sbat)
*(.sbat.*)
}
/*

View File

@ -100,7 +100,5 @@ SECTIONS {
*(.rel.*)
*(.discard)
*(.discard.*)
*(.sbat)
*(.sbat.*)
}
}

View File

@ -47,7 +47,7 @@ static char __bss16_array ( syslinux_version, [32] );
#define syslinux_version __use_data16 ( syslinux_version )
/** The "SYSLINUX" copyright string */
static char __data16_array ( syslinux_copyright, [] ) = " https://ipxe.org";
static char __data16_array ( syslinux_copyright, [] ) = " http://ipxe.org";
#define syslinux_copyright __use_data16 ( syslinux_copyright )
static char __data16_array ( syslinux_configuration_file, [] ) = "";

View File

@ -161,7 +161,7 @@ pnpheader:
/* Manufacturer string */
mfgstr:
.asciz "https://ipxe.org"
.asciz "http://ipxe.org"
.size mfgstr, . - mfgstr
/* Product string
@ -607,7 +607,7 @@ get_pmm_decompress_to:
* strings PRODUCT_NAME and PRODUCT_SHORT_NAME in config/branding.h.
*
* While nothing in the GPL prevents you from removing all references
* to iPXE or https://ipxe.org, we prefer you not to do so.
* to iPXE or http://ipxe.org, we prefer you not to do so.
*
* If you have an OEM-mandated branding requirement that cannot be
* satisfied simply by defining PRODUCT_NAME and PRODUCT_SHORT_NAME,

View File

@ -229,8 +229,6 @@ SECTIONS {
*(.einfo.*)
*(.discard)
*(.discard.*)
*(.sbat)
*(.sbat.*)
}
/*

View File

@ -24,8 +24,6 @@ SECTIONS {
*(.einfo.*)
*(.discard)
*(.discard.*)
*(.sbat)
*(.sbat.*)
}
}

View File

@ -100,7 +100,5 @@ SECTIONS {
*(.rel.*)
*(.discard)
*(.discard.*)
*(.sbat)
*(.sbat.*)
}
}

View File

@ -26,7 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*/
#define PRODUCT_NAME ""
#define PRODUCT_SHORT_NAME "iPXE"
#define PRODUCT_URI "https://ipxe.org"
#define PRODUCT_URI "http://ipxe.org"
/*
* Tag line
@ -44,15 +44,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* (e.g. "Permission denied") and a 32-bit error number. This number
* is incorporated into an error URI such as
*
* "No such file or directory (https://ipxe.org/2d0c613b)"
* "No such file or directory (http://ipxe.org/2d0c613b)"
*
* or
*
* "Operation not supported (https://ipxe.org/3c092003)"
* "Operation not supported (http://ipxe.org/3c092003)"
*
* Users may browse to the URI within the error message, which is
* provided by a database running on the iPXE web site
* (https://ipxe.org). This database provides details for all possible
* (http://ipxe.org). This database provides details for all possible
* errors generated by iPXE, including:
*
* - the detailed error message (e.g. "Not an OCSP signing
@ -74,13 +74,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
* If you have a customer support team and would like your customers
* to contact your support team for all problems, instead of using the
* existing support infrastructure provided by https://ipxe.org, then
* existing support infrastructure provided by http://ipxe.org, then
* you may define a custom URI to be included within error messages.
*
* Note that the custom URI is a printf() format string which must
* include a format specifier for the 32-bit error number.
*/
#define PRODUCT_ERROR_URI "https://ipxe.org/%08x"
#define PRODUCT_ERROR_URI "http://ipxe.org/%08x"
/*
* Command help messages
@ -88,7 +88,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* iPXE command help messages include a URI constructed from the
* command name, such as
*
* "See https://ipxe.org/cmd/vcreate for further information"
* "See http://ipxe.org/cmd/vcreate for further information"
*
* The iPXE web site includes documentation for the commands provided
* by the iPXE shell, including:
@ -113,7 +113,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
* If you want to provide your own documentation for all of the
* commands provided by the iPXE shell, rather than using the existing
* support infrastructure provided by https://ipxe.org, then you may
* support infrastructure provided by http://ipxe.org, then you may
* define a custom URI to be included within command help messages.
*
* Note that the custom URI is a printf() format string which must
@ -124,7 +124,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* iPXE project and prohibit the alteration or removal of any
* references to "iPXE". ]
*/
#define PRODUCT_COMMAND_URI "https://ipxe.org/cmd/%s"
#define PRODUCT_COMMAND_URI "http://ipxe.org/cmd/%s"
/*
* Setting help messages
@ -132,7 +132,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* iPXE setting help messages include a URI constructed from the
* setting name, such as
*
* "https://ipxe.org/cfg/initiator-iqn"
* "http://ipxe.org/cfg/initiator-iqn"
*
* The iPXE web site includes documentation for the settings used by
* iPXE, including:
@ -156,7 +156,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
* If you want to provide your own documentation for all of the
* settings used by iPXE, rather than using the existing support
* infrastructure provided by https://ipxe.org, then you may define a
* infrastructure provided by http://ipxe.org, then you may define a
* custom URI to be included within setting help messages.
*
* Note that the custom URI is a printf() format string which must
@ -167,25 +167,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* iPXE project and prohibit the alteration or removal of any
* references to "iPXE". ]
*/
#define PRODUCT_SETTING_URI "https://ipxe.org/cfg/%s"
/*
* Product security name suffix
*
* Vendors creating signed iPXE binaries must set this to a non-empty
* value (e.g. "2pint").
*/
#define PRODUCT_SBAT_NAME ""
/*
* Product security generation
*
* Vendors creating signed iPXE binaries must set this to a non-zero
* value, and must increment the value whenever a Secure Boot exploit
* is fixed (unless the upstream IPXE_SBAT_GENERATION has already been
* incremented as part of that fix).
*/
#define PRODUCT_SBAT_GENERATION 0
#define PRODUCT_SETTING_URI "http://ipxe.org/cfg/%s"
#include <config/local/branding.h>

View File

@ -2199,7 +2199,7 @@ const struct setting_type setting_type_base64 __setting_type = {
};
/**
* Format UUID/GUID setting value
* Format UUID setting value
*
* @v type Setting type
* @v raw Raw setting value
@ -2208,24 +2208,17 @@ const struct setting_type setting_type_base64 __setting_type = {
* @v len Length of buffer
* @ret len Length of formatted value, or negative error
*/
static int format_uuid_setting ( const struct setting_type *type,
static int format_uuid_setting ( const struct setting_type *type __unused,
const void *raw, size_t raw_len, char *buf,
size_t len ) {
union uuid uuid;
const union uuid *uuid = raw;
/* Range check */
if ( raw_len != sizeof ( uuid ) )
if ( raw_len != sizeof ( *uuid ) )
return -ERANGE;
/* Copy value */
memcpy ( &uuid, raw, sizeof ( uuid ) );
/* Mangle GUID byte ordering */
if ( type == &setting_type_guid )
uuid_mangle ( &uuid );
/* Format value */
return snprintf ( buf, len, "%s", uuid_ntoa ( &uuid ) );
return snprintf ( buf, len, "%s", uuid_ntoa ( uuid ) );
}
/** UUID setting type */
@ -2234,12 +2227,6 @@ const struct setting_type setting_type_uuid __setting_type = {
.format = format_uuid_setting,
};
/** GUID setting type */
const struct setting_type setting_type_guid __setting_type = {
.name = "guid",
.format = format_uuid_setting,
};
/**
* Format PCI bus:dev.fn setting value
*

View File

@ -334,15 +334,8 @@ struct uri * parse_uri ( const char *uri_string ) {
uri->efragment = tmp;
}
/* Identify absolute URIs */
epath = raw;
for ( tmp = raw ; ; tmp++ ) {
/* Possible scheme character (for our URI schemes) */
if ( isalpha ( *tmp ) || ( *tmp == '-' ) || ( *tmp == '_' ) )
continue;
/* Invalid scheme character or NUL: is a relative URI */
if ( *tmp != ':' )
break;
/* Identify absolute/relative URI */
if ( ( tmp = strchr ( raw, ':' ) ) ) {
/* Absolute URI: identify hierarchical/opaque */
uri->scheme = raw;
*(tmp++) = '\0';
@ -354,7 +347,9 @@ struct uri * parse_uri ( const char *uri_string ) {
uri->opaque = tmp;
epath = NULL;
}
break;
} else {
/* Relative URI */
epath = raw;
}
/* If we don't have a path (i.e. we have an absolute URI with

View File

@ -32,7 +32,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <wchar.h>
#include <ipxe/features.h>
#include <ipxe/version.h>
#include <ipxe/sbat.h>
#include <config/general.h>
#include <config/branding.h>
@ -93,32 +92,3 @@ const wchar_t build_wname[] = WSTRING ( BUILD_NAME );
/** Copy of build name string within ".prefix" */
const char build_name_prefix[] __attribute__ (( section ( ".prefix.name" ) ))
= BUILD_NAME;
/** SBAT upstream iPXE line
*
* This line represents the security generation of the upstream
* codebase from which this build is derived.
*/
#define SBAT_IPXE \
SBAT_LINE ( "ipxe", IPXE_SBAT_GENERATION, \
"iPXE", BUILD_NAME, VERSION, "https://ipxe.org" )
/** SBAT local build line
*
* This line states the security generation of the local build, which
* may include non-default features or non-upstreamed modifications.
*/
#if PRODUCT_SBAT_GENERATION
#define SBAT_PRODUCT \
SBAT_LINE ( "ipxe." PRODUCT_SBAT_NAME, PRODUCT_SBAT_GENERATION, \
PRODUCT_SHORT_NAME, BUILD_NAME, VERSION, \
PRODUCT_URI )
#else
#define SBAT_PRODUCT ""
#endif
/** SBAT data */
#define SBAT_DATA SBAT_HEADER "" SBAT_IPXE "" SBAT_PRODUCT
/** SBAT data (without any NUL terminator) */
const char sbat[ sizeof ( SBAT_DATA ) - 1 ] __sbat = SBAT_DATA;

View File

@ -576,7 +576,7 @@ static int nii_issue_cpb_db ( struct nii_nic *nii, unsigned int op, void *cpb,
cdb.IFnum = nii->nii->IfNum;
/* Raise task priority level */
tpl = bs->RaiseTPL ( efi_internal_tpl );
tpl = bs->RaiseTPL ( TPL_CALLBACK );
/* Issue command */
DBGC2 ( nii, "NII %s issuing %02x:%04x ifnum %d%s%s\n",

View File

@ -164,10 +164,6 @@ static int snpnet_transmit ( struct net_device *netdev,
EFI_STATUS efirc;
int rc;
/* Do nothing if shutdown is in progress */
if ( efi_shutdown_in_progress )
return -ECANCELED;
/* Defer the packet if there is already a transmission in progress */
if ( snp->txbuf ) {
netdev_tx_defer ( netdev, iobuf );
@ -287,10 +283,6 @@ static void snpnet_poll_rx ( struct net_device *netdev ) {
*/
static void snpnet_poll ( struct net_device *netdev ) {
/* Do nothing if shutdown is in progress */
if ( efi_shutdown_in_progress )
return;
/* Process any TX completions */
snpnet_poll_tx ( netdev );
@ -434,9 +426,8 @@ static void snpnet_close ( struct net_device *netdev ) {
EFI_STATUS efirc;
int rc;
/* Shut down NIC (unless whole system shutdown is in progress) */
if ( ( ! efi_shutdown_in_progress ) &&
( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) ) {
/* Shut down NIC */
if ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( snp, "SNP %s could not shut down: %s\n",
netdev->name, strerror ( rc ) );
@ -598,9 +589,8 @@ void snpnet_stop ( struct efi_device *efidev ) {
/* Unregister network device */
unregister_netdev ( netdev );
/* Stop SNP protocol (unless whole system shutdown is in progress) */
if ( ( ! efi_shutdown_in_progress ) &&
( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) ) {
/* Stop SNP protocol */
if ( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( device, "SNP %s could not stop: %s\n",
efi_handle_name ( device ), strerror ( rc ) );

View File

@ -481,7 +481,6 @@ static struct pci_device_id intelx_nics[] = {
PCI_ROM ( 0x8086, 0x15ab, "x552", "X552", 0 ),
PCI_ROM ( 0x8086, 0x15c8, "x553t", "X553/X557-AT", 0 ),
PCI_ROM ( 0x8086, 0x15ce, "x553-sfp", "X553 (SFP+)", 0 ),
PCI_ROM ( 0x8086, 0x15e4, "x553a", "X553", 0 ),
PCI_ROM ( 0x8086, 0x15e5, "x553", "X553", 0 ),
};

View File

@ -223,7 +223,6 @@ extern EFI_HANDLE efi_image_handle;
extern EFI_LOADED_IMAGE_PROTOCOL *efi_loaded_image;
extern EFI_DEVICE_PATH_PROTOCOL *efi_loaded_image_path;
extern EFI_SYSTEM_TABLE *efi_systab;
extern EFI_TPL efi_internal_tpl;
extern EFI_TPL efi_external_tpl;
extern int efi_shutdown_in_progress;

View File

@ -10,7 +10,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
extern EFI_BOOT_SERVICES * efi_wrap_bs ( void );
extern EFI_SYSTEM_TABLE * efi_wrap_systab ( void );
extern void efi_wrap ( EFI_HANDLE handle );
#endif /* _IPXE_EFI_WRAP_H */

View File

@ -1,68 +0,0 @@
#ifndef _IPXE_SBAT_H
#define _IPXE_SBAT_H
/** @file
*
* Secure Boot Advanced Targeting (SBAT)
*
* SBAT defines an encoding for security generation numbers stored as
* a CSV file within a special ".sbat" section in the signed binary.
* If a Secure Boot exploit is discovered then the generation number
* will be incremented alongside the corresponding fix.
*
* Platforms may then record the minimum generation number required
* for any given product. This allows for an efficient revocation
* mechanism that consumes minimal flash storage space (in contrast to
* the DBX mechanism, which allows for only a single-digit number of
* revocation events to ever take place across all possible signed
* binaries).
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* A single line within an SBAT CSV file
*
* @v name Machine-readable component name
* @v generation Security generation number
* @v vendor Human-readable vendor name
* @v package Human-readable package name
* @v version Human-readable package version
* @v uri Contact URI
* @ret line CSV line
*/
#define SBAT_LINE( name, generation, vendor, package, version, uri ) \
name "," _S2 ( generation ) "," vendor "," package "," \
version "," uri "\n"
/** SBAT format generation */
#define SBAT_GENERATION 1
/** Upstream security generation
*
* This represents the security generation of the upstream codebase.
* It will be incremented whenever a Secure Boot exploit is fixed in
* the upstream codebase.
*
* If you do not have commit access to the upstream iPXE repository,
* then you may not modify this value under any circumstances.
*/
#define IPXE_SBAT_GENERATION 1
/* Seriously, do not modify this value */
#if IPXE_SBAT_GENERATION != 1
#error "You may not modify IPXE_SBAT_GENERATION"
#endif
/** SBAT header line */
#define SBAT_HEADER \
SBAT_LINE ( "sbat", SBAT_GENERATION, "SBAT Version", "sbat", \
_S2 ( SBAT_GENERATION ), \
"https://github.com/rhboot/shim/blob/main/SBAT.md" )
/** Mark variable as being in the ".sbat" section */
#define __sbat __attribute__ (( section ( ".sbat" ), aligned ( 512 ) ))
extern const char sbat[] __sbat;
#endif /* _IPXE_SBAT_H */

View File

@ -426,7 +426,6 @@ extern const struct setting_type setting_type_hexhyp __setting_type;
extern const struct setting_type setting_type_hexraw __setting_type;
extern const struct setting_type setting_type_base64 __setting_type;
extern const struct setting_type setting_type_uuid __setting_type;
extern const struct setting_type setting_type_guid __setting_type;
extern const struct setting_type setting_type_busdevfn __setting_type;
extern const struct setting_type setting_type_dnssl __setting_type;

View File

@ -774,7 +774,7 @@ struct srp_aer_rsp {
* The working draft specification for the SRP boot firmware table can
* be found at
*
* https://ipxe.org/wiki/srp/sbft
* http://ipxe.org/wiki/srp/sbft
*
*****************************************************************************
*/

View File

@ -104,8 +104,8 @@ static void efi_entropy_disable ( void ) {
/* Close timer tick event */
bs->CloseEvent ( tick );
/* Return to internal TPL */
bs->RaiseTPL ( efi_internal_tpl );
/* Return to TPL_CALLBACK */
bs->RaiseTPL ( TPL_CALLBACK );
}
/**

View File

@ -47,9 +47,6 @@ EFI_DEVICE_PATH_PROTOCOL *efi_loaded_image_path;
*/
EFI_SYSTEM_TABLE * _C2 ( PLATFORM, _systab );
/** Internal task priority level */
EFI_TPL efi_internal_tpl = TPL_CALLBACK;
/** External task priority level */
EFI_TPL efi_external_tpl = TPL_APPLICATION;
@ -82,17 +79,6 @@ static EFI_STATUS EFIAPI efi_unload ( EFI_HANDLE image_handle );
static EFIAPI void efi_shutdown_hook ( EFI_EVENT event __unused,
void *context __unused ) {
/* This callback is invoked at TPL_NOTIFY in order to ensure
* that we have an opportunity to shut down cleanly before
* other shutdown hooks perform destructive operations such as
* disabling the IOMMU.
*
* Modify the internal task priority level so that no code
* attempts to raise from TPL_NOTIFY to TPL_CALLBACK (which
* would trigger a fatal exception).
*/
efi_internal_tpl = TPL_NOTIFY;
/* Mark shutdown as being in progress, to indicate that large
* parts of the system (e.g. timers) are no longer functional.
*/
@ -287,7 +273,7 @@ EFI_STATUS efi_init ( EFI_HANDLE image_handle,
* bother doing so when ExitBootServices() is called.
*/
if ( ( efirc = bs->CreateEvent ( EVT_SIGNAL_EXIT_BOOT_SERVICES,
TPL_NOTIFY, efi_shutdown_hook,
TPL_CALLBACK, efi_shutdown_hook,
NULL, &efi_shutdown_event ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( systab, "EFI could not create ExitBootServices event: "
@ -330,13 +316,9 @@ EFI_STATUS efi_init ( EFI_HANDLE image_handle,
static EFI_STATUS EFIAPI efi_unload ( EFI_HANDLE image_handle __unused ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_SYSTEM_TABLE *systab = efi_systab;
struct efi_saved_tpl tpl;
DBGC ( systab, "EFI image unloading\n" );
/* Raise TPL */
efi_raise_tpl ( &tpl );
/* Shut down */
shutdown_exit();
@ -354,9 +336,6 @@ static EFI_STATUS EFIAPI efi_unload ( EFI_HANDLE image_handle __unused ) {
DBGC ( systab, "EFI image unloaded\n" );
/* Restore TPL */
efi_restore_tpl ( &tpl );
return 0;
}
@ -387,7 +366,7 @@ __attribute__ (( noreturn )) void __stack_chk_fail ( void ) {
}
/**
* Raise task priority level to internal level
* Raise task priority level to TPL_CALLBACK
*
* @v tpl Saved TPL
*/
@ -398,7 +377,7 @@ void efi_raise_tpl ( struct efi_saved_tpl *tpl ) {
tpl->previous = efi_external_tpl;
/* Raise TPL and record previous TPL as new external TPL */
tpl->current = bs->RaiseTPL ( efi_internal_tpl );
tpl->current = bs->RaiseTPL ( TPL_CALLBACK );
efi_external_tpl = tpl->current;
}

View File

@ -137,7 +137,7 @@ static unsigned long efi_currticks ( void ) {
efi_jiffies++;
} else {
bs->RestoreTPL ( efi_external_tpl );
bs->RaiseTPL ( efi_internal_tpl );
bs->RaiseTPL ( TPL_CALLBACK );
}
return ( efi_jiffies * ( TICKS_PER_SEC / EFI_JIFFIES_PER_SEC ) );

View File

@ -34,7 +34,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <string.h>
#include <ipxe/retry.h>
#include <ipxe/timer.h>
#include <ipxe/init.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_watchdog.h>
@ -81,36 +80,3 @@ static void efi_watchdog_expired ( struct retry_timer *timer,
/** Watchdog holdoff timer */
struct retry_timer efi_watchdog = TIMER_INIT ( efi_watchdog_expired );
/**
* Disable watching when shutting down to boot an operating system
*
* @v booting System is shutting down for OS boot
*/
static void efi_watchdog_shutdown ( int booting ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_STATUS efirc;
int rc;
/* If we are shutting down to boot an operating system, then
* disable the boot services watchdog timer. The UEFI
* specification mandates that the platform firmware does this
* as part of the ExitBootServices() call, but some platforms
* (e.g. Hyper-V) are observed to occasionally forget to do
* so, resulting in a reboot approximately five minutes after
* starting the operating system.
*/
if ( booting &&
( ( efirc = bs->SetWatchdogTimer ( 0, 0, 0, NULL ) ) != 0 ) ) {
rc = -EEFI ( efirc );
DBGC ( &efi_watchdog, "EFI could not disable watchdog timer: "
"%s\n", strerror ( rc ) );
/* Nothing we can do */
}
}
/** Watchdog startup/shutdown function */
struct startup_fn efi_watchdog_startup_fn __startup_fn ( STARTUP_EARLY ) = {
.name = "efi_watchdog",
.shutdown = efi_watchdog_shutdown,
};

View File

@ -195,47 +195,6 @@ static const char * efi_timer_delay ( EFI_TIMER_DELAY type ) {
}
}
/**
* Dump information about a loaded image
*
* @v handle Image handle
*/
static void efi_dump_image ( EFI_HANDLE handle ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
union {
EFI_LOADED_IMAGE_PROTOCOL *image;
void *intf;
} loaded;
EFI_STATUS efirc;
int rc;
/* Open loaded image protocol */
if ( ( efirc = bs->OpenProtocol ( handle,
&efi_loaded_image_protocol_guid,
&loaded.intf, efi_image_handle, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
rc = -EEFI ( efirc );
DBGC ( colour, "WRAP %s could not get loaded image protocol: "
"%s\n", efi_handle_name ( handle ), strerror ( rc ) );
return;
}
/* Dump image information */
DBGC ( colour, "WRAP %s at base %p has protocols:\n",
efi_handle_name ( handle ), loaded.image->ImageBase );
DBGC_EFI_PROTOCOLS ( colour, handle );
DBGC ( colour, "WRAP %s parent", efi_handle_name ( handle ) );
DBGC ( colour, " %s\n", efi_handle_name ( loaded.image->ParentHandle ));
DBGC ( colour, "WRAP %s device", efi_handle_name ( handle ) );
DBGC ( colour, " %s\n", efi_handle_name ( loaded.image->DeviceHandle ));
DBGC ( colour, "WRAP %s file", efi_handle_name ( handle ) );
DBGC ( colour, " %s\n", efi_devpath_text ( loaded.image->FilePath ) );
/* Close loaded image protocol */
bs->CloseProtocol ( handle, &efi_loaded_image_protocol_guid,
efi_image_handle, NULL );
}
/**
* Wrap RaiseTPL()
*
@ -696,9 +655,9 @@ efi_load_image_wrapper ( BOOLEAN boot_policy, EFI_HANDLE parent_image_handle,
DBGC ( colour, "%s ", efi_handle_name ( *image_handle ) );
DBGC ( colour, ") -> %p\n", retaddr );
/* Dump information about loaded image */
/* Wrap the new image */
if ( efirc == 0 )
efi_dump_image ( *image_handle );
efi_wrap ( *image_handle );
return efirc;
}
@ -776,14 +735,11 @@ efi_exit_boot_services_wrapper ( EFI_HANDLE image_handle, UINTN map_key ) {
void *retaddr = __builtin_return_address ( 0 );
EFI_STATUS efirc;
DBGC ( colour, "ExitBootServices ( %s, %#llx ) -> %p\n",
DBGC ( colour, "ExitBootServices ( %s, %#llx ) ",
efi_handle_name ( image_handle ),
( ( unsigned long long ) map_key ), retaddr );
( ( unsigned long long ) map_key ) );
efirc = bs->ExitBootServices ( image_handle, map_key );
if ( efirc != 0 ) {
DBGC ( colour, "ExitBootServices ( ... ) = %s -> %p\n",
efi_status ( efirc ), retaddr );
}
DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
return efirc;
}
@ -1173,11 +1129,12 @@ efi_create_event_ex_wrapper ( UINT32 type, EFI_TPL notify_tpl,
}
/**
* Build boot services table wrapper
* Build table wrappers
*
* @ret bs Wrapped boot services table
* @ret systab Wrapped system table
*/
EFI_BOOT_SERVICES * efi_wrap_bs ( void ) {
EFI_SYSTEM_TABLE * efi_wrap_systab ( void ) {
static EFI_SYSTEM_TABLE efi_systab_wrapper;
static EFI_BOOT_SERVICES efi_bs_wrapper;
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
@ -1237,7 +1194,12 @@ EFI_BOOT_SERVICES * efi_wrap_bs ( void ) {
= efi_uninstall_multiple_protocol_interfaces_wrapper;
efi_bs_wrapper.CreateEventEx = efi_create_event_ex_wrapper;
return &efi_bs_wrapper;
/* Build system table wrapper */
memcpy ( &efi_systab_wrapper, efi_systab,
sizeof ( efi_systab_wrapper ) );
efi_systab_wrapper.BootServices = &efi_bs_wrapper;
return &efi_systab_wrapper;
}
/**
@ -1246,20 +1208,42 @@ EFI_BOOT_SERVICES * efi_wrap_bs ( void ) {
* @v handle Image handle
*/
void efi_wrap ( EFI_HANDLE handle ) {
static EFI_SYSTEM_TABLE efi_systab_copy;
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
union {
EFI_LOADED_IMAGE_PROTOCOL *image;
void *intf;
} loaded;
EFI_STATUS efirc;
int rc;
/* Do nothing unless debugging is enabled */
if ( ! DBG_LOG )
return;
/* Construct modified system table */
if ( efi_systab != &efi_systab_copy ) {
memcpy ( &efi_systab_copy, efi_systab,
sizeof ( efi_systab_copy ) );
efi_systab->BootServices = efi_wrap_bs();
efi_systab = &efi_systab_copy;
/* Open loaded image protocol */
if ( ( efirc = bs->OpenProtocol ( handle,
&efi_loaded_image_protocol_guid,
&loaded.intf, efi_image_handle, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
rc = -EEFI ( efirc );
DBGC ( colour, "WRAP %s could not get loaded image protocol: "
"%s\n", efi_handle_name ( handle ), strerror ( rc ) );
return;
}
/* Dump image information */
efi_dump_image ( handle );
/* Provide system table wrapper to image */
loaded.image->SystemTable = efi_wrap_systab();
DBGC ( colour, "WRAP %s at base %p has protocols:\n",
efi_handle_name ( handle ), loaded.image->ImageBase );
DBGC_EFI_PROTOCOLS ( colour, handle );
DBGC ( colour, "WRAP %s parent", efi_handle_name ( handle ) );
DBGC ( colour, " %s\n", efi_handle_name ( loaded.image->ParentHandle ));
DBGC ( colour, "WRAP %s device", efi_handle_name ( handle ) );
DBGC ( colour, " %s\n", efi_handle_name ( loaded.image->DeviceHandle ));
DBGC ( colour, "WRAP %s file", efi_handle_name ( handle ) );
DBGC ( colour, " %s\n", efi_devpath_text ( loaded.image->FilePath ) );
/* Close loaded image protocol */
bs->CloseProtocol ( handle, &efi_loaded_image_protocol_guid,
efi_image_handle, NULL );
}

View File

@ -140,8 +140,7 @@ static int smbios_fetch ( struct settings *settings __unused,
* is 2.6 or higher; we match this behaviour.
*/
raw = &buf[tag_offset];
if ( ( ( setting->type == &setting_type_uuid ) ||
( setting->type == &setting_type_guid ) ) &&
if ( ( setting->type == &setting_type_uuid ) &&
( tag_len == sizeof ( uuid ) ) &&
( smbios_version() >= SMBIOS_VERSION ( 2, 6 ) ) ) {
DBG ( "SMBIOS detected mangled UUID\n" );

View File

@ -74,19 +74,6 @@ SECTIONS {
_ebss = .;
}
/*
* The SBAT section
*
*/
. = ALIGN ( _page_align );
.sbat : {
_sbat = .;
KEEP(*(.sbat))
KEEP(*(.sbat.*))
_esbat = .;
}
/*
* Weak symbols that need zero values if not otherwise defined
*

View File

@ -250,12 +250,6 @@ static struct setting test_uuid_setting = {
.type = &setting_type_uuid,
};
/** Test GUID setting type */
static struct setting test_guid_setting = {
.name = "test_guid",
.type = &setting_type_guid,
};
/** Test PCI bus:dev.fn setting type */
static struct setting test_busdevfn_setting = {
.name = "test_busdevfn",
@ -425,10 +419,6 @@ static void settings_test_exec ( void ) {
RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a,0xa8,
0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ),
"1a6a749d-0eda-461a-a87a-7cfe4fca4a57" );
fetchf_ok ( &test_settings, &test_guid_setting,
RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a,0xa8,
0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ),
"9d746a1a-da0e-1a46-a87a-7cfe4fca4a57" );
/* "busdevfn" setting type (no store capability) */
fetchf_ok ( &test_settings, &test_busdevfn_setting,

View File

@ -657,15 +657,6 @@ static struct uri_test uri_file_volume = {
},
};
/** Relative URI with colons in path */
static struct uri_test uri_colons = {
"/boot/52:54:00:12:34:56/boot.ipxe",
{
.path = "/boot/52:54:00:12:34:56/boot.ipxe",
.epath = "/boot/52:54:00:12:34:56/boot.ipxe",
},
};
/** URI with port number */
static struct uri_port_test uri_explicit_port = {
"http://192.168.0.1:8080/boot.php",
@ -966,7 +957,6 @@ static void uri_test_exec ( void ) {
uri_parse_format_dup_ok ( &uri_file_relative );
uri_parse_format_dup_ok ( &uri_file_absolute );
uri_parse_format_dup_ok ( &uri_file_volume );
uri_parse_format_dup_ok ( &uri_colons );
/** URI port number tests */
uri_port_ok ( &uri_explicit_port );

View File

@ -579,8 +579,8 @@ int ipxe ( struct net_device *netdev ) {
* defining the string PRODUCT_NAME in config/branding.h.
*
* While nothing in the GPL prevents you from removing all
* references to iPXE or https://ipxe.org, we prefer you not
* to do so.
* references to iPXE or http://ipxe.org, we prefer you not to
* do so.
*
*/
printf ( NORMAL "\n\n" PRODUCT_NAME "\n" BOLD PRODUCT_SHORT_NAME " %s"

View File

@ -753,13 +753,15 @@ static struct pe_section *
create_reloc_section ( struct pe_header *pe_header,
struct pe_relocs *pe_reltab ) {
struct pe_section *reloc;
size_t section_rawsz;
size_t section_memsz;
size_t section_filesz;
EFI_IMAGE_DATA_DIRECTORY *relocdir;
/* Allocate PE section */
section_memsz = output_pe_reltab ( pe_reltab, NULL );
section_filesz = efi_file_align ( section_memsz );
section_rawsz = output_pe_reltab ( pe_reltab, NULL );
section_filesz = efi_file_align ( section_rawsz );
section_memsz = efi_image_align ( section_rawsz );
reloc = xmalloc ( sizeof ( *reloc ) + section_filesz );
memset ( reloc, 0, sizeof ( *reloc ) + section_filesz );
@ -780,12 +782,11 @@ create_reloc_section ( struct pe_header *pe_header,
/* Update file header details */
pe_header->nt.FileHeader.NumberOfSections++;
pe_header->nt.OptionalHeader.SizeOfHeaders += sizeof ( reloc->hdr );
pe_header->nt.OptionalHeader.SizeOfImage +=
efi_image_align ( section_memsz );
pe_header->nt.OptionalHeader.SizeOfImage += section_memsz;
relocdir = &(pe_header->nt.OptionalHeader.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]);
relocdir->VirtualAddress = reloc->hdr.VirtualAddress;
relocdir->Size = section_memsz;
relocdir->Size = section_rawsz;
return reloc;
}
@ -823,8 +824,8 @@ create_debug_section ( struct pe_header *pe_header, const char *filename ) {
} *contents;
/* Allocate PE section */
section_memsz = sizeof ( *contents );
section_filesz = efi_file_align ( section_memsz );
section_memsz = efi_image_align ( sizeof ( *contents ) );
section_filesz = efi_file_align ( sizeof ( *contents ) );
debug = xmalloc ( sizeof ( *debug ) + section_filesz );
memset ( debug, 0, sizeof ( *debug ) + section_filesz );
contents = ( void * ) debug->contents;
@ -856,8 +857,7 @@ create_debug_section ( struct pe_header *pe_header, const char *filename ) {
/* Update file header details */
pe_header->nt.FileHeader.NumberOfSections++;
pe_header->nt.OptionalHeader.SizeOfHeaders += sizeof ( debug->hdr );
pe_header->nt.OptionalHeader.SizeOfImage +=
efi_image_align ( section_memsz );
pe_header->nt.OptionalHeader.SizeOfImage += section_memsz;
debugdir = &(pe_header->nt.OptionalHeader.DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
debugdir->VirtualAddress = debug->hdr.VirtualAddress;

View File

@ -308,9 +308,6 @@ if [ -n "${ISOIMG}" ] ; then
${ISOARGS} "${ISODIR}"
if isohybrid --version >/dev/null 2>&1 ; then
ISOHYBRIDARGS=
if [ -n "${EFI}" ] ; then
ISOHYBRIDARGS="${ISOHYBRIDARGS} --uefi"
fi
if [ -n "${SOURCE_DATE_EPOCH:-}" ] ; then
ISOHYBRIDARGS="${ISOHYBRIDARGS} --id ${SOURCE_DATE_EPOCH}"
fi

View File

@ -565,7 +565,7 @@ EOM
return join("\n", @output);
}
# Output NIC list in DokuWiki format (for https://ipxe.org)
# Output NIC list in DokuWiki format (for http://ipxe.org)
sub format_nic_list_dokuwiki {
my ($nic_list, $column_names) = @_;
my @output;