summaryrefslogtreecommitdiffstats
path: root/src/interface
diff options
context:
space:
mode:
Diffstat (limited to 'src/interface')
-rw-r--r--src/interface/efi/efi_driver.c15
-rw-r--r--src/interface/efi/efi_entropy.c4
-rw-r--r--src/interface/efi/efi_init.c34
-rw-r--r--src/interface/efi/efi_snp.c58
-rw-r--r--src/interface/efi/efi_timer.c15
-rw-r--r--src/interface/efi/efi_usb.c36
-rw-r--r--src/interface/efi/efidrvprefix.c8
7 files changed, 99 insertions, 71 deletions
diff --git a/src/interface/efi/efi_driver.c b/src/interface/efi/efi_driver.c
index 8388dd535..8e537d535 100644
--- a/src/interface/efi/efi_driver.c
+++ b/src/interface/efi/efi_driver.c
@@ -156,13 +156,13 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_driver *efidrv;
struct efi_device *efidev;
+ struct efi_saved_tpl tpl;
union {
EFI_DEVICE_PATH_PROTOCOL *path;
void *interface;
} path;
EFI_DEVICE_PATH_PROTOCOL *path_end;
size_t path_len;
- EFI_TPL saved_tpl;
EFI_STATUS efirc;
int rc;
@@ -181,7 +181,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
}
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Do nothing if we are currently disconnecting drivers */
if ( efi_driver_disconnecting ) {
@@ -236,7 +236,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
DBGC ( device, "EFIDRV %s using driver \"%s\"\n",
efi_handle_name ( device ),
efidev->driver->name );
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
return 0;
}
DBGC ( device, "EFIDRV %s could not start driver \"%s\": %s\n",
@@ -254,7 +254,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
}
err_open_path:
err_disconnecting:
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
err_already_started:
return efirc;
}
@@ -273,10 +273,9 @@ static EFI_STATUS EFIAPI
efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
EFI_HANDLE device, UINTN num_children,
EFI_HANDLE *children ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_driver *efidrv;
struct efi_device *efidev;
- EFI_TPL saved_tpl;
+ struct efi_saved_tpl tpl;
UINTN i;
DBGC ( device, "EFIDRV %s DRIVER_STOP", efi_handle_name ( device ) );
@@ -295,7 +294,7 @@ efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
}
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Stop this device */
efidrv = efidev->driver;
@@ -304,7 +303,7 @@ efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
list_del ( &efidev->dev.siblings );
free ( efidev );
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
return 0;
}
diff --git a/src/interface/efi/efi_entropy.c b/src/interface/efi/efi_entropy.c
index dca0b6f1d..70cd06293 100644
--- a/src/interface/efi/efi_entropy.c
+++ b/src/interface/efi/efi_entropy.c
@@ -79,8 +79,8 @@ static int efi_entropy_enable ( void ) {
DBGC ( &tick, "ENTROPY %s RNG protocol\n",
( efirng ? "has" : "has no" ) );
- /* Drop to TPL_APPLICATION to allow timer tick event to take place */
- bs->RestoreTPL ( TPL_APPLICATION );
+ /* Drop to external TPL to allow timer tick event to take place */
+ bs->RestoreTPL ( efi_external_tpl );
/* Create timer tick event */
if ( ( efirc = bs->CreateEvent ( EVT_TIMER, TPL_NOTIFY, NULL, NULL,
diff --git a/src/interface/efi/efi_init.c b/src/interface/efi/efi_init.c
index 6d46c5669..b7cac16e5 100644
--- a/src/interface/efi/efi_init.c
+++ b/src/interface/efi/efi_init.c
@@ -47,6 +47,9 @@ EFI_DEVICE_PATH_PROTOCOL *efi_loaded_image_path;
*/
EFI_SYSTEM_TABLE * _C2 ( PLATFORM, _systab );
+/** External task priority level */
+EFI_TPL efi_external_tpl = TPL_APPLICATION;
+
/** EFI shutdown is in progress */
int efi_shutdown_in_progress;
@@ -361,3 +364,34 @@ __attribute__ (( noreturn )) void __stack_chk_fail ( void ) {
while ( 1 ) {}
}
+
+/**
+ * Raise task priority level to TPL_CALLBACK
+ *
+ * @v tpl Saved TPL
+ */
+void efi_raise_tpl ( struct efi_saved_tpl *tpl ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+
+ /* Record current external TPL */
+ tpl->previous = efi_external_tpl;
+
+ /* Raise TPL and record previous TPL as new external TPL */
+ tpl->current = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_external_tpl = tpl->current;
+}
+
+/**
+ * Restore task priority level
+ *
+ * @v tpl Saved TPL
+ */
+void efi_restore_tpl ( struct efi_saved_tpl *tpl ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+
+ /* Restore external TPL */
+ efi_external_tpl = tpl->previous;
+
+ /* Restore TPL */
+ bs->RestoreTPL ( tpl->current );
+}
diff --git a/src/interface/efi/efi_snp.c b/src/interface/efi/efi_snp.c
index 5285d322b..c1ce90427 100644
--- a/src/interface/efi/efi_snp.c
+++ b/src/interface/efi/efi_snp.c
@@ -48,7 +48,7 @@ static LIST_HEAD ( efi_snp_devices );
static int efi_snp_claimed;
/** TPL prior to network devices being claimed */
-static EFI_TPL efi_snp_old_tpl;
+static struct efi_saved_tpl efi_snp_saved_tpl;
/* Downgrade user experience if configured to do so
*
@@ -235,10 +235,9 @@ efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
static EFI_STATUS EFIAPI
efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
- EFI_TPL saved_tpl;
+ struct efi_saved_tpl tpl;
int rc;
DBGC ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
@@ -252,7 +251,7 @@ efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
}
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Open network device */
if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
@@ -263,7 +262,7 @@ efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
efi_snp_set_state ( snpdev );
err_open:
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
err_claimed:
return EFIRC ( rc );
}
@@ -277,10 +276,9 @@ efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
*/
static EFI_STATUS EFIAPI
efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
- EFI_TPL saved_tpl;
+ struct efi_saved_tpl tpl;
int rc;
DBGC ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
@@ -293,7 +291,7 @@ efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
}
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Close network device */
netdev_close ( snpdev->netdev );
@@ -309,7 +307,7 @@ efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
efi_snp_set_state ( snpdev );
err_open:
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
err_claimed:
return EFIRC ( rc );
}
@@ -322,10 +320,9 @@ efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
*/
static EFI_STATUS EFIAPI
efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
- EFI_TPL saved_tpl;
+ struct efi_saved_tpl tpl;
DBGC ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
@@ -334,7 +331,7 @@ efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
return EFI_NOT_READY;
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Close network device */
netdev_close ( snpdev->netdev );
@@ -342,7 +339,7 @@ efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
efi_snp_flush ( snpdev );
/* Restore TPL */
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
return 0;
}
@@ -546,10 +543,9 @@ efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read,
static EFI_STATUS EFIAPI
efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
UINT32 *interrupts, VOID **txbuf ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
- EFI_TPL saved_tpl;
+ struct efi_saved_tpl tpl;
DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
@@ -560,7 +556,7 @@ efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
}
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Poll the network device */
efi_snp_poll ( snpdev );
@@ -585,7 +581,7 @@ efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
}
/* Restore TPL */
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
DBGC2 ( snpdev, "\n" );
return 0;
@@ -608,14 +604,13 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
UINTN ll_header_len, UINTN len, VOID *data,
EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
UINT16 *net_proto ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
+ struct efi_saved_tpl tpl;
struct io_buffer *iobuf;
size_t payload_len;
unsigned int tx_fill;
- EFI_TPL saved_tpl;
int rc;
DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
@@ -642,7 +637,7 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
}
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Sanity checks */
if ( ll_header_len ) {
@@ -727,7 +722,7 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
snpdev->interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
/* Restore TPL */
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
return 0;
@@ -737,7 +732,7 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
free_iob ( iobuf );
err_alloc_iob:
err_sanity:
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
err_claimed:
return EFIRC ( rc );
}
@@ -759,17 +754,16 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
UINTN *ll_header_len, UINTN *len, VOID *data,
EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
UINT16 *net_proto ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev =
container_of ( snp, struct efi_snp_device, snp );
struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
+ struct efi_saved_tpl tpl;
struct io_buffer *iobuf;
const void *iob_ll_dest;
const void *iob_ll_src;
uint16_t iob_net_proto;
unsigned int iob_flags;
size_t copy_len;
- EFI_TPL saved_tpl;
int rc;
DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
@@ -782,7 +776,7 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
}
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Poll the network device */
efi_snp_poll ( snpdev );
@@ -831,7 +825,7 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
out_bad_ll_header:
free_iob ( iobuf );
out_no_packet:
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
err_claimed:
return EFIRC ( rc );
}
@@ -844,9 +838,8 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
*/
static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
VOID *context ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev = context;
- EFI_TPL saved_tpl;
+ struct efi_saved_tpl tpl;
DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
@@ -859,13 +852,13 @@ static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
return;
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Poll the network device */
efi_snp_poll ( snpdev );
/* Restore TPL */
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
}
/** SNP interface */
@@ -1967,12 +1960,11 @@ struct efi_snp_device * last_opened_snpdev ( void ) {
* @v delta Claim count change
*/
void efi_snp_add_claim ( int delta ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev;
/* Raise TPL if we are about to claim devices */
if ( ! efi_snp_claimed )
- efi_snp_old_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &efi_snp_saved_tpl );
/* Claim SNP devices */
efi_snp_claimed += delta;
@@ -1984,5 +1976,5 @@ void efi_snp_add_claim ( int delta ) {
/* Restore TPL if we have released devices */
if ( ! efi_snp_claimed )
- bs->RestoreTPL ( efi_snp_old_tpl );
+ efi_restore_tpl ( &efi_snp_saved_tpl );
}
diff --git a/src/interface/efi/efi_timer.c b/src/interface/efi/efi_timer.c
index 8f40cb81a..405cd3454 100644
--- a/src/interface/efi/efi_timer.c
+++ b/src/interface/efi/efi_timer.c
@@ -97,8 +97,17 @@ static unsigned long efi_currticks ( void ) {
* gain us any substantive benefits (since even with such
* calls we would still be suffering from the limitations of a
* polling design), we instead choose to run at TPL_CALLBACK
- * almost all of the time, dropping to TPL_APPLICATION to
- * allow timer ticks to occur.
+ * almost all of the time, dropping to a lower TPL to allow
+ * timer ticks to occur.
+ *
+ * We record the external TPL at the point of entry into iPXE,
+ * and drop back only as far as this external TPL. This
+ * avoids the unexpected behaviour that may arise from having
+ * iPXE temporarily drop to TPL_APPLICATION in the middle of
+ * an entry point invoked at TPL_CALLBACK. The side effect is
+ * that iPXE's view of the system time is effectively frozen
+ * for the duration of any call made in to iPXE at
+ * TPL_CALLBACK or higher.
*
*
* For added excitement, UEFI provides no clean way for device
@@ -127,7 +136,7 @@ static unsigned long efi_currticks ( void ) {
if ( efi_shutdown_in_progress ) {
efi_jiffies++;
} else {
- bs->RestoreTPL ( TPL_APPLICATION );
+ bs->RestoreTPL ( efi_external_tpl );
bs->RaiseTPL ( TPL_CALLBACK );
}
diff --git a/src/interface/efi/efi_usb.c b/src/interface/efi/efi_usb.c
index 55b5bc880..bcf156999 100644
--- a/src/interface/efi/efi_usb.c
+++ b/src/interface/efi/efi_usb.c
@@ -551,7 +551,6 @@ efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,
EFI_USB_DATA_DIRECTION direction,
UINT32 timeout, VOID *data, UINTN len,
UINT32 *status ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_usb_interface *usbintf =
container_of ( usbio, struct efi_usb_interface, usbio );
struct efi_usb_device *usbdev = usbintf->usbdev;
@@ -559,7 +558,7 @@ efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,
USB_REQUEST_TYPE ( packet->Request ) );
unsigned int value = le16_to_cpu ( packet->Value );
unsigned int index = le16_to_cpu ( packet->Index );
- EFI_TPL saved_tpl;
+ struct efi_saved_tpl tpl;
int rc;
DBGC2 ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %s %dms "
@@ -569,7 +568,7 @@ efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,
( ( size_t ) len ) );
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Clear status */
*status = 0;
@@ -613,7 +612,7 @@ efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,
err_control:
err_change_config:
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
return EFIRC ( rc );
}
@@ -631,12 +630,11 @@ efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,
static EFI_STATUS EFIAPI
efi_usb_bulk_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data,
UINTN *len, UINTN timeout, UINT32 *status ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_usb_interface *usbintf =
container_of ( usbio, struct efi_usb_interface, usbio );
struct efi_usb_device *usbdev = usbintf->usbdev;
size_t actual = *len;
- EFI_TPL saved_tpl;
+ struct efi_saved_tpl tpl;
int rc;
DBGC2 ( usbdev, "USBDEV %s bulk %s %p+%zx %dms\n", usbintf->name,
@@ -644,7 +642,7 @@ efi_usb_bulk_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data,
( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Clear status */
*status = 0;
@@ -659,7 +657,7 @@ efi_usb_bulk_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data,
}
err_transfer:
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
return EFIRC ( rc );
}
@@ -678,12 +676,11 @@ static EFI_STATUS EFIAPI
efi_usb_sync_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
VOID *data, UINTN *len, UINTN timeout,
UINT32 *status ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_usb_interface *usbintf =
container_of ( usbio, struct efi_usb_interface, usbio );
struct efi_usb_device *usbdev = usbintf->usbdev;
size_t actual = *len;
- EFI_TPL saved_tpl;
+ struct efi_saved_tpl tpl;
int rc;
DBGC2 ( usbdev, "USBDEV %s sync intr %s %p+%zx %dms\n", usbintf->name,
@@ -691,7 +688,7 @@ efi_usb_sync_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
( ( size_t ) *len ), ( ( unsigned int ) timeout ) );
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Clear status */
*status = 0;
@@ -706,7 +703,7 @@ efi_usb_sync_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
}
err_transfer:
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
return EFIRC ( rc );
}
@@ -727,11 +724,10 @@ efi_usb_async_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
BOOLEAN start, UINTN interval, UINTN len,
EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
VOID *context ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_usb_interface *usbintf =
container_of ( usbio, struct efi_usb_interface, usbio );
struct efi_usb_device *usbdev = usbintf->usbdev;
- EFI_TPL saved_tpl;
+ struct efi_saved_tpl tpl;
int rc;
DBGC2 ( usbdev, "USBDEV %s async intr %s len %#zx int %d %p/%p\n",
@@ -741,7 +737,7 @@ efi_usb_async_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
callback, context );
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Start/stop transfer as applicable */
if ( start ) {
@@ -763,7 +759,7 @@ efi_usb_async_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
}
err_start:
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
return EFIRC ( rc );
}
@@ -959,9 +955,9 @@ efi_usb_get_string_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT16 language,
container_of ( usbio, struct efi_usb_interface, usbio );
struct efi_usb_device *usbdev = usbintf->usbdev;
struct usb_descriptor_header header;
+ struct efi_saved_tpl tpl;
VOID *buffer;
size_t len;
- EFI_TPL saved_tpl;
EFI_STATUS efirc;
int rc;
@@ -969,7 +965,7 @@ efi_usb_get_string_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT16 language,
usbintf->name, language, index );
/* Raise TPL */
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Read descriptor header */
if ( ( rc = usb_get_descriptor ( usbdev->func->usb, 0,
@@ -1012,7 +1008,7 @@ efi_usb_get_string_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT16 language,
memset ( ( buffer + len - sizeof ( header ) ), 0, sizeof ( **string ) );
/* Restore TPL */
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
/* Return allocated string */
*string = buffer;
@@ -1023,7 +1019,7 @@ efi_usb_get_string_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT16 language,
err_alloc:
err_len:
err_get_header:
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
return EFIRC ( rc );
}
diff --git a/src/interface/efi/efidrvprefix.c b/src/interface/efi/efidrvprefix.c
index ac7d94374..9ca54ff4f 100644
--- a/src/interface/efi/efidrvprefix.c
+++ b/src/interface/efi/efidrvprefix.c
@@ -34,8 +34,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
*/
EFI_STATUS EFIAPI _efidrv_start ( EFI_HANDLE image_handle,
EFI_SYSTEM_TABLE *systab ) {
- EFI_BOOT_SERVICES *bs;
- EFI_TPL saved_tpl;
+ static struct efi_saved_tpl tpl; /* avoid triggering stack protector */
EFI_STATUS efirc;
/* Initialise stack cookie */
@@ -46,15 +45,14 @@ EFI_STATUS EFIAPI _efidrv_start ( EFI_HANDLE image_handle,
return efirc;
/* Raise TPL */
- bs = efi_systab->BootServices;
- saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ efi_raise_tpl ( &tpl );
/* Initialise iPXE environment */
initialise();
startup();
/* Restore TPL */
- bs->RestoreTPL ( saved_tpl );
+ efi_restore_tpl ( &tpl );
return 0;
}