mirror of https://github.com/ipxe/ipxe.git
[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>vbox
parent
9a118322a0
commit
c832580f19
|
@ -37,8 +37,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** A driver veto */
|
/** A driver veto candidate */
|
||||||
struct efi_veto {
|
struct efi_veto_candidate {
|
||||||
/** Veto name (for debugging) */
|
/** Veto name (for debugging) */
|
||||||
const char *name;
|
const char *name;
|
||||||
/**
|
/**
|
||||||
|
@ -57,14 +57,27 @@ struct efi_veto {
|
||||||
const char *manufacturer, const CHAR16 *name );
|
const char *manufacturer, const CHAR16 *name );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** A driver veto */
|
||||||
|
struct efi_veto {
|
||||||
|
/** Driver binding handle */
|
||||||
|
EFI_HANDLE driver;
|
||||||
|
/** Driving binding protocol */
|
||||||
|
EFI_DRIVER_BINDING_PROTOCOL *binding;
|
||||||
|
/** Image handle */
|
||||||
|
EFI_HANDLE image;
|
||||||
|
/** Loaded image protocol */
|
||||||
|
EFI_LOADED_IMAGE_PROTOCOL *loaded;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unload an EFI driver
|
* Unload an EFI driver
|
||||||
*
|
*
|
||||||
* @v driver Driver binding handle
|
* @v veto Driver veto
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int efi_veto_unload ( EFI_HANDLE driver ) {
|
static int efi_veto_unload ( struct efi_veto *veto ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
|
EFI_HANDLE driver = veto->driver;
|
||||||
EFI_STATUS efirc;
|
EFI_STATUS efirc;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -82,11 +95,12 @@ static int efi_veto_unload ( EFI_HANDLE driver ) {
|
||||||
/**
|
/**
|
||||||
* Disconnect an EFI driver from all handles
|
* Disconnect an EFI driver from all handles
|
||||||
*
|
*
|
||||||
* @v driver Driver binding handle
|
* @v veto Driver veto
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int efi_veto_disconnect ( EFI_HANDLE driver ) {
|
static int efi_veto_disconnect ( struct efi_veto *veto ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
|
EFI_HANDLE driver = veto->driver;
|
||||||
EFI_HANDLE *handles;
|
EFI_HANDLE *handles;
|
||||||
EFI_HANDLE handle;
|
EFI_HANDLE handle;
|
||||||
UINTN count;
|
UINTN count;
|
||||||
|
@ -131,11 +145,12 @@ static int efi_veto_disconnect ( EFI_HANDLE driver ) {
|
||||||
/**
|
/**
|
||||||
* Uninstall an EFI driver binding protocol
|
* Uninstall an EFI driver binding protocol
|
||||||
*
|
*
|
||||||
* @v driver Driver binding handle
|
* @v veto Driver veto
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int efi_veto_uninstall ( EFI_HANDLE driver ) {
|
static int efi_veto_uninstall ( struct efi_veto *veto ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
|
EFI_HANDLE driver = veto->driver;
|
||||||
union {
|
union {
|
||||||
EFI_DRIVER_BINDING_PROTOCOL *binding;
|
EFI_DRIVER_BINDING_PROTOCOL *binding;
|
||||||
void *interface;
|
void *interface;
|
||||||
|
@ -178,14 +193,15 @@ static int efi_veto_uninstall ( EFI_HANDLE driver ) {
|
||||||
/**
|
/**
|
||||||
* Close protocol on handle potentially opened by an EFI driver
|
* Close protocol on handle potentially opened by an EFI driver
|
||||||
*
|
*
|
||||||
* @v driver Driver binding handle
|
* @v veto Driver veto
|
||||||
* @v handle Potentially opened handle
|
* @v handle Potentially opened handle
|
||||||
* @v protocol Opened protocol
|
* @v protocol Opened protocol
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int efi_veto_close_protocol ( EFI_HANDLE driver, EFI_HANDLE handle,
|
static int efi_veto_close_protocol ( struct efi_veto *veto, EFI_HANDLE handle,
|
||||||
EFI_GUID *protocol ) {
|
EFI_GUID *protocol ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
|
EFI_HANDLE driver = veto->driver;
|
||||||
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *openers;
|
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *openers;
|
||||||
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *opener;
|
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *opener;
|
||||||
EFI_HANDLE controller;
|
EFI_HANDLE controller;
|
||||||
|
@ -235,12 +251,13 @@ static int efi_veto_close_protocol ( EFI_HANDLE driver, EFI_HANDLE handle,
|
||||||
/**
|
/**
|
||||||
* Close handle potentially opened by an EFI driver
|
* Close handle potentially opened by an EFI driver
|
||||||
*
|
*
|
||||||
* @v driver Driver binding handle
|
* @v veto Driver veto
|
||||||
* @v handle Potentially opened handle
|
* @v handle Potentially opened handle
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int efi_veto_close_handle ( EFI_HANDLE driver, EFI_HANDLE handle ) {
|
static int efi_veto_close_handle ( struct efi_veto *veto, EFI_HANDLE handle ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
|
EFI_HANDLE driver = veto->driver;
|
||||||
EFI_GUID **protocols;
|
EFI_GUID **protocols;
|
||||||
UINTN count;
|
UINTN count;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -260,7 +277,7 @@ static int efi_veto_close_handle ( EFI_HANDLE driver, EFI_HANDLE handle ) {
|
||||||
|
|
||||||
/* Close each protocol */
|
/* Close each protocol */
|
||||||
for ( i = 0 ; i < count ; i++ ) {
|
for ( i = 0 ; i < count ; i++ ) {
|
||||||
if ( ( rc = efi_veto_close_protocol ( driver, handle,
|
if ( ( rc = efi_veto_close_protocol ( veto, handle,
|
||||||
protocols[i] ) ) != 0 )
|
protocols[i] ) ) != 0 )
|
||||||
goto err_close;
|
goto err_close;
|
||||||
}
|
}
|
||||||
|
@ -277,11 +294,12 @@ static int efi_veto_close_handle ( EFI_HANDLE driver, EFI_HANDLE handle ) {
|
||||||
/**
|
/**
|
||||||
* Close all remaining handles opened by an EFI driver
|
* Close all remaining handles opened by an EFI driver
|
||||||
*
|
*
|
||||||
* @v driver Driver binding handle
|
* @v veto Driver veto
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int efi_veto_close ( EFI_HANDLE driver ) {
|
static int efi_veto_close ( struct efi_veto *veto ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
|
EFI_HANDLE driver = veto->driver;
|
||||||
EFI_HANDLE *handles;
|
EFI_HANDLE *handles;
|
||||||
UINTN count;
|
UINTN count;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -299,8 +317,7 @@ static int efi_veto_close ( EFI_HANDLE driver ) {
|
||||||
|
|
||||||
/* Close each handle */
|
/* Close each handle */
|
||||||
for ( i = 0 ; i < count ; i++ ) {
|
for ( i = 0 ; i < count ; i++ ) {
|
||||||
if ( ( rc = efi_veto_close_handle ( driver,
|
if ( ( rc = efi_veto_close_handle ( veto, handles[i] ) ) != 0 )
|
||||||
handles[i] ) ) != 0 )
|
|
||||||
goto err_close;
|
goto err_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,22 +335,23 @@ static int efi_veto_close ( EFI_HANDLE driver ) {
|
||||||
/**
|
/**
|
||||||
* Terminate an EFI driver with extreme prejudice
|
* Terminate an EFI driver with extreme prejudice
|
||||||
*
|
*
|
||||||
* @v driver Driver binding handle
|
* @v veto Driver veto
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int efi_veto_destroy ( EFI_HANDLE driver ) {
|
static int efi_veto_destroy ( struct efi_veto *veto ) {
|
||||||
|
EFI_HANDLE driver = veto->driver;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Disconnect driver from all handles */
|
/* Disconnect driver from all handles */
|
||||||
if ( ( rc = efi_veto_disconnect ( driver ) ) != 0 )
|
if ( ( rc = efi_veto_disconnect ( veto ) ) != 0 )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* Uninstall driver binding protocol */
|
/* Uninstall driver binding protocol */
|
||||||
if ( ( rc = efi_veto_uninstall ( driver ) ) != 0 )
|
if ( ( rc = efi_veto_uninstall ( veto ) ) != 0 )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* Close any remaining opened handles */
|
/* Close any remaining opened handles */
|
||||||
if ( ( rc = efi_veto_close ( driver ) ) != 0 )
|
if ( ( rc = efi_veto_close ( veto ) ) != 0 )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
DBGC ( driver, "EFIVETO %s forcibly removed\n",
|
DBGC ( driver, "EFIVETO %s forcibly removed\n",
|
||||||
|
@ -344,18 +362,18 @@ static int efi_veto_destroy ( EFI_HANDLE driver ) {
|
||||||
/**
|
/**
|
||||||
* Veto an EFI driver
|
* Veto an EFI driver
|
||||||
*
|
*
|
||||||
* @v driver Driver binding handle
|
* @v veto Driver veto
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int efi_veto_driver ( EFI_HANDLE driver ) {
|
static int efi_veto_driver ( struct efi_veto *veto ) {
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Try gracefully unloading the driver */
|
/* Try gracefully unloading the driver */
|
||||||
if ( ( rc = efi_veto_unload ( driver ) ) == 0 )
|
if ( ( rc = efi_veto_unload ( veto ) ) == 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If that fails, use a hammer */
|
/* If that fails, use a hammer */
|
||||||
if ( ( rc = efi_veto_destroy ( driver ) ) == 0 )
|
if ( ( rc = efi_veto_destroy ( veto ) ) == 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -467,7 +485,7 @@ efi_veto_vmware_uefipxebc ( EFI_DRIVER_BINDING_PROTOCOL *binding __unused,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Driver vetoes */
|
/** Driver vetoes */
|
||||||
static struct efi_veto efi_vetoes[] = {
|
static struct efi_veto_candidate efi_vetoes[] = {
|
||||||
{
|
{
|
||||||
.name = "Ip4Config",
|
.name = "Ip4Config",
|
||||||
.veto = efi_veto_ip4config,
|
.veto = efi_veto_ip4config,
|
||||||
|
@ -487,11 +505,11 @@ static struct efi_veto efi_vetoes[] = {
|
||||||
*
|
*
|
||||||
* @v driver Driver binding handle
|
* @v driver Driver binding handle
|
||||||
* @v manufacturer Manufacturer name, if present
|
* @v manufacturer Manufacturer name, if present
|
||||||
* @ret veto Driver veto, or NULL
|
* @ret veto Driver veto to fill in
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
static int efi_veto_find ( EFI_HANDLE driver, const char *manufacturer,
|
static int efi_veto_find ( EFI_HANDLE driver, const char *manufacturer,
|
||||||
struct efi_veto **veto ) {
|
struct efi_veto *veto ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
union {
|
union {
|
||||||
EFI_DRIVER_BINDING_PROTOCOL *binding;
|
EFI_DRIVER_BINDING_PROTOCOL *binding;
|
||||||
|
@ -515,7 +533,7 @@ static int efi_veto_find ( EFI_HANDLE driver, const char *manufacturer,
|
||||||
efi_handle_name ( driver ) );
|
efi_handle_name ( driver ) );
|
||||||
|
|
||||||
/* Mark as not vetoed */
|
/* Mark as not vetoed */
|
||||||
*veto = NULL;
|
memset ( veto, 0, sizeof ( *veto ) );
|
||||||
|
|
||||||
/* Open driver binding protocol */
|
/* Open driver binding protocol */
|
||||||
if ( ( efirc = bs->OpenProtocol (
|
if ( ( efirc = bs->OpenProtocol (
|
||||||
|
@ -567,7 +585,13 @@ static int efi_veto_find ( EFI_HANDLE driver, const char *manufacturer,
|
||||||
sizeof ( efi_vetoes[0] ) ) ; i++ ) {
|
sizeof ( efi_vetoes[0] ) ) ; i++ ) {
|
||||||
if ( efi_vetoes[i].veto ( binding.binding, loaded.loaded,
|
if ( efi_vetoes[i].veto ( binding.binding, loaded.loaded,
|
||||||
wtf.wtf, manufacturer, name ) ) {
|
wtf.wtf, manufacturer, name ) ) {
|
||||||
*veto = &efi_vetoes[i];
|
DBGC ( driver, "EFIVETO %s is vetoed (%s)\n",
|
||||||
|
efi_handle_name ( driver ),
|
||||||
|
efi_vetoes[i].name );
|
||||||
|
veto->driver = driver;
|
||||||
|
veto->binding = binding.binding;
|
||||||
|
veto->image = image;
|
||||||
|
veto->loaded = loaded.loaded;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,7 +619,7 @@ static int efi_veto_find ( EFI_HANDLE driver, const char *manufacturer,
|
||||||
*/
|
*/
|
||||||
void efi_veto ( void ) {
|
void efi_veto ( void ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_veto *veto;
|
struct efi_veto veto;
|
||||||
EFI_HANDLE *drivers;
|
EFI_HANDLE *drivers;
|
||||||
EFI_HANDLE driver;
|
EFI_HANDLE driver;
|
||||||
UINTN num_drivers;
|
UINTN num_drivers;
|
||||||
|
@ -629,11 +653,9 @@ void efi_veto ( void ) {
|
||||||
efi_handle_name ( driver ), strerror ( rc ) );
|
efi_handle_name ( driver ), strerror ( rc ) );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( ! veto )
|
if ( ! veto.driver )
|
||||||
continue;
|
continue;
|
||||||
DBGC ( driver, "EFIVETO %s is vetoed (%s)\n",
|
if ( ( rc = efi_veto_driver ( &veto ) ) != 0 ) {
|
||||||
efi_handle_name ( driver ), veto->name );
|
|
||||||
if ( ( rc = efi_veto_driver ( driver ) ) != 0 ) {
|
|
||||||
DBGC ( driver, "EFIVETO %s could not veto: %s\n",
|
DBGC ( driver, "EFIVETO %s could not veto: %s\n",
|
||||||
efi_handle_name ( driver ), strerror ( rc ) );
|
efi_handle_name ( driver ), strerror ( rc ) );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue