summaryrefslogtreecommitdiffstats
path: root/src/interface/efi
diff options
context:
space:
mode:
authorMichael Brown2018-03-15 00:55:28 +0100
committerMichael Brown2018-03-15 00:55:28 +0100
commit10d083ffa93e2cc5c69c8f963720ce4d48c5cf6f (patch)
tree0ed802160bf6c2b3622b07bb72dd7506f4180752 /src/interface/efi
parent[efi] Drop to TPL_APPLICATION when gathering entropy (diff)
downloadipxe-10d083ffa93e2cc5c69c8f963720ce4d48c5cf6f.tar.gz
ipxe-10d083ffa93e2cc5c69c8f963720ce4d48c5cf6f.tar.xz
ipxe-10d083ffa93e2cc5c69c8f963720ce4d48c5cf6f.zip
[efi] Raise TPL within EFI_DRIVER_BINDING_PROTOCOL entry points
Debugged-by: Rob Taglang <rob@privatemachines.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/interface/efi')
-rw-r--r--src/interface/efi/efi_driver.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/interface/efi/efi_driver.c b/src/interface/efi/efi_driver.c
index de0f61f9..fe73630f 100644
--- a/src/interface/efi/efi_driver.c
+++ b/src/interface/efi/efi_driver.c
@@ -95,7 +95,9 @@ struct efi_device * efidev_parent ( struct device *dev ) {
static EFI_STATUS EFIAPI
efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_driver *efidrv;
+ EFI_TPL saved_tpl;
int rc;
DBGCP ( device, "EFIDRV %s DRIVER_SUPPORTED",
@@ -111,17 +113,22 @@ efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
return EFI_ALREADY_STARTED;
}
+ /* Raise TPL */
+ saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+
/* Look for a driver claiming to support this device */
for_each_table_entry ( efidrv, EFI_DRIVERS ) {
if ( ( rc = efidrv->supported ( device ) ) == 0 ) {
DBGC ( device, "EFIDRV %s has driver \"%s\"\n",
efi_handle_name ( device ), efidrv->name );
+ bs->RestoreTPL ( saved_tpl );
return 0;
}
}
DBGCP ( device, "EFIDRV %s has no driver\n",
efi_handle_name ( device ) );
+ bs->RestoreTPL ( saved_tpl );
return EFI_UNSUPPORTED;
}
@@ -145,6 +152,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
} path;
EFI_DEVICE_PATH_PROTOCOL *path_end;
size_t path_len;
+ EFI_TPL saved_tpl;
EFI_STATUS efirc;
int rc;
@@ -162,6 +170,9 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
goto err_already_started;
}
+ /* Raise TPL */
+ saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+
/* Do nothing if we are currently disconnecting drivers */
if ( efi_driver_disconnecting ) {
DBGC ( device, "EFIDRV %s refusing to start during "
@@ -215,6 +226,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 );
return 0;
}
DBGC ( device, "EFIDRV %s could not start driver \"%s\": %s\n",
@@ -232,6 +244,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
}
err_open_path:
err_disconnecting:
+ bs->RestoreTPL ( saved_tpl );
err_already_started:
return efirc;
}
@@ -250,8 +263,10 @@ 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;
UINTN i;
DBGC ( device, "EFIDRV %s DRIVER_STOP", efi_handle_name ( device ) );
@@ -269,6 +284,9 @@ efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
return EFI_DEVICE_ERROR;
}
+ /* Raise TPL */
+ saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
+
/* Stop this device */
efidrv = efidev->driver;
assert ( efidrv != NULL );
@@ -276,6 +294,7 @@ efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
list_del ( &efidev->dev.siblings );
free ( efidev );
+ bs->RestoreTPL ( saved_tpl );
return 0;
}