mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
MdeModulePkg: Add optional variable runtime hooks
Add a default-disabled protocol that lets platforms run pre- and post-hooks around runtime SetVariable MM communication. Discover the first valid provider before EndOfDxe and convert cached callbacks for runtime use. Require EFI_SUCCESS from each pre-hook before entering MM. Every independent runtime request invokes the provider so it can serialize shared platform resources. Signed-off-by: Marc Chen <marc.chen@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
86ecae29c6
commit
c108a8bfff
6 changed files with 515 additions and 5 deletions
84
MdeModulePkg/Include/Protocol/VariableSmmRuntimeDxeHook.h
Normal file
84
MdeModulePkg/Include/Protocol/VariableSmmRuntimeDxeHook.h
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/** @file
|
||||
Optional hooks around VariableSmmRuntimeDxe SetVariable() MM communication.
|
||||
|
||||
A provider must be a DXE_RUNTIME_DRIVER, or otherwise guarantee that its code
|
||||
and data remain runtime-resident. It must not use boot services or allocate
|
||||
boot-services memory after ExitBootServices().
|
||||
|
||||
Hook inputs are untrusted runtime-service inputs. Providers must validate all
|
||||
inputs they consume, bound all waits, and must not call SetVariable() from
|
||||
either hook. These hooks do not replace SMM validation, VarCheck, variable
|
||||
policy, Secure Boot authentication, MOR handling, or flash-write
|
||||
authorization.
|
||||
|
||||
A provider MAY access MMIO, PIO, mailbox, or device resources reserved
|
||||
exclusively for firmware and not exposed to or accessed by the OS. If a
|
||||
resource may also be accessed by the OS, the provider MUST use a
|
||||
platform-defined ownership or synchronization mechanism shared with the OS.
|
||||
UEFI locks and TPL do not synchronize with OS drivers. For this contract,
|
||||
"not exposed to the OS" means absent from OS discovery and description
|
||||
mechanisms such as ACPI, PCI BAR assignment, and device tree. It is not
|
||||
sufficient that the currently loaded OS driver does not use the resource.
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define EDKII_VARIABLE_RUNTIME_HOOK_PROTOCOL_GUID \
|
||||
{ \
|
||||
0xdeddcd7a, 0xd76d, 0x46a3, { 0xba, 0xa5, 0xbf, 0x25, 0x50, 0x77, 0xdc, 0x10 } \
|
||||
}
|
||||
|
||||
/**
|
||||
Invoked immediately before runtime SetVariable() communication is sent to MM.
|
||||
|
||||
The provider owns its runtime-safe synchronization state. The interface
|
||||
intentionally carries no opaque per-operation context.
|
||||
|
||||
@param[in] VariableName Name of the variable.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
@param[in] Attributes Variable attributes.
|
||||
@param[in] DataSize Size of Data in bytes.
|
||||
@param[in] Data Variable data.
|
||||
|
||||
@retval EFI_SUCCESS Continue with the existing MM variable service.
|
||||
@retval Others Reject or defer the operation without entering MM.
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EDKII_VARIABLE_PRE_SET_VARIABLE)(
|
||||
IN CONST CHAR16 *VariableName,
|
||||
IN CONST EFI_GUID *VendorGuid,
|
||||
IN UINT32 Attributes,
|
||||
IN UINTN DataSize,
|
||||
IN CONST VOID *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Invoked after runtime SetVariable() communication completes.
|
||||
|
||||
This notification is called only when PreSetVariable() returned success.
|
||||
SetVariableStatus is authoritative and is returned unchanged by the existing
|
||||
variable service.
|
||||
|
||||
@param[in] SetVariableStatus Result from the existing MM variable service.
|
||||
**/
|
||||
typedef
|
||||
VOID
|
||||
(EFIAPI *EDKII_VARIABLE_POST_SET_VARIABLE)(
|
||||
IN EFI_STATUS SetVariableStatus
|
||||
);
|
||||
|
||||
///
|
||||
/// This protocol is optional. Both callbacks are required. The first valid
|
||||
/// provider discovered before EndOfDxe is used.
|
||||
///
|
||||
typedef struct {
|
||||
EDKII_VARIABLE_PRE_SET_VARIABLE PreSetVariable;
|
||||
EDKII_VARIABLE_POST_SET_VARIABLE PostSetVariable;
|
||||
} EDKII_VARIABLE_RUNTIME_HOOK_PROTOCOL;
|
||||
|
||||
extern EFI_GUID gEdkiiVariableSmmRuntimeDxeHookProtocolGuid;
|
||||
|
|
@ -639,6 +639,10 @@
|
|||
# Include/Protocol/VariableLock.h
|
||||
gEdkiiVariableLockProtocolGuid = { 0xcd3d0a05, 0x9e24, 0x437c, { 0xa8, 0x91, 0x1e, 0xe0, 0x53, 0xdb, 0x76, 0x38 }}
|
||||
|
||||
## Optional hooks around runtime SetVariable() MM communication.
|
||||
# Include/Protocol/VariableSmmRuntimeDxeHook.h
|
||||
gEdkiiVariableSmmRuntimeDxeHookProtocolGuid = { 0xdeddcd7a, 0xd76d, 0x46a3, { 0xba, 0xa5, 0xbf, 0x25, 0x50, 0x77, 0xdc, 0x10 }}
|
||||
|
||||
## Include/Protocol/VarCheck.h
|
||||
gEdkiiVarCheckProtocolGuid = { 0xaf23b340, 0x97b4, 0x4685, { 0x8d, 0x4f, 0xa3, 0xf2, 0x81, 0x69, 0xb2, 0x1d } }
|
||||
|
||||
|
|
@ -801,6 +805,12 @@
|
|||
# @Prompt Enable the UEFI variable runtime cache.
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache|TRUE|BOOLEAN|0x00010039
|
||||
|
||||
## Indicates if optional hooks around runtime SetVariable() MM communication are enabled.<BR><BR>
|
||||
# TRUE - Discover and invoke the variable runtime hook protocol.<BR>
|
||||
# FALSE - Do not discover or invoke the variable runtime hook protocol.<BR>
|
||||
# @Prompt Enable variable runtime hooks.
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableSmmRuntimeDxeHook|FALSE|BOOLEAN|0x00010043
|
||||
|
||||
## Indicates if the statistics about variable usage will be collected. This information is
|
||||
# stored as a vendor configuration table into the EFI system table.
|
||||
# Set this PCD to TRUE to use VariableInfo application in MdeModulePkg\Application directory to get
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
|
||||
#include "PrivilegePolymorphic.h"
|
||||
#include "VariableParsing.h"
|
||||
#include "VariableSmmRuntimeDxeHookInternal.h"
|
||||
|
||||
EFI_HANDLE mHandle = NULL;
|
||||
EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable = NULL;
|
||||
|
|
@ -1154,6 +1155,7 @@ RuntimeServiceSetVariable (
|
|||
UINTN PayloadSize;
|
||||
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *SmmVariableHeader;
|
||||
UINTN VariableNameSize;
|
||||
BOOLEAN HookInvoked;
|
||||
|
||||
//
|
||||
// Check input parameters.
|
||||
|
|
@ -1178,6 +1180,21 @@ RuntimeServiceSetVariable (
|
|||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
HookInvoked = FALSE;
|
||||
if (FeaturePcdGet (PcdEnableVariableSmmRuntimeDxeHook)) {
|
||||
Status = VariableRuntimeHookPreSetVariable (
|
||||
VariableName,
|
||||
VendorGuid,
|
||||
Attributes,
|
||||
DataSize,
|
||||
Data,
|
||||
&HookInvoked
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
AcquireLockOnlyAtBootTime (&mVariableServicesLock);
|
||||
|
||||
//
|
||||
|
|
@ -1207,6 +1224,10 @@ RuntimeServiceSetVariable (
|
|||
Done:
|
||||
ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
|
||||
|
||||
if (FeaturePcdGet (PcdEnableVariableSmmRuntimeDxeHook)) {
|
||||
VariableRuntimeHookPostSetVariable (HookInvoked, Status);
|
||||
}
|
||||
|
||||
if (!EfiAtRuntime ()) {
|
||||
if (!EFI_ERROR (Status)) {
|
||||
SecureBootHook (
|
||||
|
|
@ -1307,6 +1328,10 @@ OnExitBootServices (
|
|||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
if (FeaturePcdGet (PcdEnableVariableSmmRuntimeDxeHook)) {
|
||||
VariableRuntimeHookStopDiscovery ();
|
||||
}
|
||||
|
||||
//
|
||||
// Init the communicate buffer. The buffer data size is:
|
||||
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE.
|
||||
|
|
@ -1388,6 +1413,9 @@ VariableAddressChangeEvent (
|
|||
EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRtCacheInfo.RuntimeHobCacheBuffer);
|
||||
EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRtCacheInfo.RuntimeNvCacheBuffer);
|
||||
EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mVariableRtCacheInfo.RuntimeVolatileCacheBuffer);
|
||||
if (FeaturePcdGet (PcdEnableVariableSmmRuntimeDxeHook)) {
|
||||
VariableRuntimeHookConvertPointers ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1961,14 +1989,22 @@ VariableSmmRuntimeInitialize (
|
|||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
VOID *SmmVariableRegistration;
|
||||
VOID *SmmVariableWriteRegistration;
|
||||
EFI_EVENT OnReadyToBootEvent;
|
||||
EFI_EVENT ExitBootServiceEvent;
|
||||
EFI_EVENT LegacyBootEvent;
|
||||
VOID *SmmVariableRegistration;
|
||||
VOID *SmmVariableWriteRegistration;
|
||||
EFI_EVENT OnReadyToBootEvent;
|
||||
EFI_EVENT ExitBootServiceEvent;
|
||||
EFI_EVENT LegacyBootEvent;
|
||||
EFI_STATUS Status;
|
||||
|
||||
EfiInitializeLock (&mVariableServicesLock, TPL_NOTIFY);
|
||||
|
||||
if (FeaturePcdGet (PcdEnableVariableSmmRuntimeDxeHook)) {
|
||||
Status = VariableRuntimeHookInitialize ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN, "Variable runtime hook discovery failed: %r\n", Status));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Smm variable service is ready
|
||||
//
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
|
||||
[Sources]
|
||||
VariableSmmRuntimeDxe.c
|
||||
VariableSmmRuntimeDxeHook.c
|
||||
VariableSmmRuntimeDxeHookInternal.h
|
||||
PrivilegePolymorphic.h
|
||||
Measurement.c
|
||||
VariableParsing.c
|
||||
|
|
@ -72,10 +74,12 @@
|
|||
## UNDEFINED # Used to do smm communication
|
||||
gEfiSmmVariableProtocolGuid
|
||||
gEdkiiVariableLockProtocolGuid ## PRODUCES
|
||||
gEdkiiVariableSmmRuntimeDxeHookProtocolGuid ## SOMETIMES_CONSUMES ## NOTIFY
|
||||
gEdkiiVarCheckProtocolGuid ## PRODUCES
|
||||
gEdkiiVariablePolicyProtocolGuid ## PRODUCES
|
||||
|
||||
[FeaturePcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableSmmRuntimeDxeHook ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES
|
||||
|
||||
[Pcd]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,302 @@
|
|||
/** @file
|
||||
Support for the optional VariableSmmRuntimeDxe hook protocol.
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Guid/EventGroup.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeLib.h>
|
||||
|
||||
#include "VariableSmmRuntimeDxeHookInternal.h"
|
||||
|
||||
STATIC EDKII_VARIABLE_PRE_SET_VARIABLE mPreSetVariable;
|
||||
STATIC EDKII_VARIABLE_POST_SET_VARIABLE mPostSetVariable;
|
||||
STATIC EFI_EVENT mVariableRuntimeHookNotifyEvent;
|
||||
STATIC EFI_EVENT mVariableRuntimeHookEndOfDxeEvent;
|
||||
STATIC VOID *mVariableRuntimeHookRegistration;
|
||||
STATIC BOOLEAN mVariableRuntimeHookDiscoveryEnded;
|
||||
|
||||
/**
|
||||
Caches the first valid variable runtime hook provider.
|
||||
|
||||
@param[in] Protocol Variable runtime hook protocol instance.
|
||||
|
||||
@retval TRUE The provider was valid and its callbacks were cached.
|
||||
@retval FALSE The provider was invalid or provider discovery has ended.
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
CacheVariableRuntimeHook (
|
||||
IN EDKII_VARIABLE_RUNTIME_HOOK_PROTOCOL *Protocol
|
||||
)
|
||||
{
|
||||
if (mVariableRuntimeHookDiscoveryEnded ||
|
||||
(mPreSetVariable != NULL) ||
|
||||
(Protocol == NULL) ||
|
||||
(Protocol->PreSetVariable == NULL) ||
|
||||
(Protocol->PostSetVariable == NULL))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mPreSetVariable = Protocol->PreSetVariable;
|
||||
mPostSetVariable = Protocol->PostSetVariable;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Closes an event and clears its cached event handle.
|
||||
|
||||
@param[in,out] Event Address of the cached event handle.
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
CloseVariableRuntimeHookEvent (
|
||||
IN OUT EFI_EVENT *Event
|
||||
)
|
||||
{
|
||||
EFI_EVENT EventToClose;
|
||||
|
||||
EventToClose = *Event;
|
||||
*Event = NULL;
|
||||
if (EventToClose != NULL) {
|
||||
gBS->CloseEvent (EventToClose);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Closes the variable runtime hook protocol notification event and clears its
|
||||
registration key.
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
CloseVariableRuntimeHookNotifyEvent (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
CloseVariableRuntimeHookEvent (&mVariableRuntimeHookNotifyEvent);
|
||||
mVariableRuntimeHookRegistration = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
Notification function invoked when the variable runtime hook protocol is
|
||||
installed.
|
||||
|
||||
@param[in] Event Event whose notification function is being invoked.
|
||||
@param[in] Context Pointer to the notification function context.
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
VariableRuntimeHookInstalled (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EDKII_VARIABLE_RUNTIME_HOOK_PROTOCOL *Protocol;
|
||||
|
||||
if (mVariableRuntimeHookDiscoveryEnded || (mPreSetVariable != NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
Protocol = NULL;
|
||||
Status = gBS->LocateProtocol (
|
||||
&gEdkiiVariableSmmRuntimeDxeHookProtocolGuid,
|
||||
mVariableRuntimeHookRegistration,
|
||||
(VOID **)&Protocol
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
} while (!CacheVariableRuntimeHook (Protocol));
|
||||
|
||||
CloseVariableRuntimeHookNotifyEvent ();
|
||||
}
|
||||
|
||||
/**
|
||||
Stops variable runtime hook provider discovery and closes discovery events.
|
||||
**/
|
||||
VOID
|
||||
VariableRuntimeHookStopDiscovery (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
mVariableRuntimeHookDiscoveryEnded = TRUE;
|
||||
CloseVariableRuntimeHookNotifyEvent ();
|
||||
CloseVariableRuntimeHookEvent (&mVariableRuntimeHookEndOfDxeEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
EndOfDxe notification function that accepts any pending provider and then
|
||||
stops provider discovery.
|
||||
|
||||
@param[in] Event Event whose notification function is being invoked.
|
||||
@param[in] Context Pointer to the notification function context.
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
EFIAPI
|
||||
VariableRuntimeHookEndOfDxe (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
if ((mPreSetVariable == NULL) && (mVariableRuntimeHookNotifyEvent != NULL)) {
|
||||
VariableRuntimeHookInstalled (mVariableRuntimeHookNotifyEvent, NULL);
|
||||
}
|
||||
|
||||
VariableRuntimeHookStopDiscovery ();
|
||||
}
|
||||
|
||||
/**
|
||||
Discovers the first valid variable runtime hook provider and registers for
|
||||
notification if a provider is not yet available.
|
||||
|
||||
@retval EFI_SUCCESS Discovery was initialized or a provider was cached.
|
||||
@retval Others Event or protocol notification registration failed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
VariableRuntimeHookInitialize (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EDKII_VARIABLE_RUNTIME_HOOK_PROTOCOL *Protocol;
|
||||
|
||||
if (mVariableRuntimeHookDiscoveryEnded || (mPreSetVariable != NULL)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Protocol = NULL;
|
||||
Status = gBS->LocateProtocol (
|
||||
&gEdkiiVariableSmmRuntimeDxeHookProtocolGuid,
|
||||
NULL,
|
||||
(VOID **)&Protocol
|
||||
);
|
||||
if (!EFI_ERROR (Status) && CacheVariableRuntimeHook (Protocol)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = gBS->CreateEventEx (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
VariableRuntimeHookEndOfDxe,
|
||||
NULL,
|
||||
&gEfiEndOfDxeEventGroupGuid,
|
||||
&mVariableRuntimeHookEndOfDxeEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
VariableRuntimeHookInstalled,
|
||||
NULL,
|
||||
&mVariableRuntimeHookNotifyEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
VariableRuntimeHookStopDiscovery ();
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gBS->RegisterProtocolNotify (
|
||||
&gEdkiiVariableSmmRuntimeDxeHookProtocolGuid,
|
||||
mVariableRuntimeHookNotifyEvent,
|
||||
&mVariableRuntimeHookRegistration
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
VariableRuntimeHookStopDiscovery ();
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Process providers installed between the initial lookup and registration.
|
||||
//
|
||||
VariableRuntimeHookInstalled (mVariableRuntimeHookNotifyEvent, NULL);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Converts cached variable runtime hook callback pointers to virtual addresses.
|
||||
**/
|
||||
VOID
|
||||
VariableRuntimeHookConvertPointers (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mPreSetVariable);
|
||||
EfiConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mPostSetVariable);
|
||||
}
|
||||
|
||||
/**
|
||||
Invokes the cached pre-hook for an OS runtime SetVariable() request.
|
||||
|
||||
@param[in] VariableName Name of the variable.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
@param[in] Attributes Variable attributes.
|
||||
@param[in] DataSize Size of Data in bytes.
|
||||
@param[in] Data Variable data.
|
||||
@param[out] HookInvoked TRUE if the pre-hook returned success.
|
||||
|
||||
@retval EFI_SUCCESS Continue with MM communication.
|
||||
@retval Others The pre-hook rejected or deferred the operation.
|
||||
**/
|
||||
EFI_STATUS
|
||||
VariableRuntimeHookPreSetVariable (
|
||||
IN CONST CHAR16 *VariableName,
|
||||
IN CONST EFI_GUID *VendorGuid,
|
||||
IN UINT32 Attributes,
|
||||
IN UINTN DataSize,
|
||||
IN CONST VOID *Data,
|
||||
OUT BOOLEAN *HookInvoked
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
*HookInvoked = FALSE;
|
||||
if (!EfiAtRuntime () || (mPreSetVariable == NULL)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = mPreSetVariable (
|
||||
VariableName,
|
||||
VendorGuid,
|
||||
Attributes,
|
||||
DataSize,
|
||||
Data
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
*HookInvoked = TRUE;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Invokes the cached post-hook after MM communication completes.
|
||||
|
||||
@param[in] HookInvoked TRUE if the pre-hook returned success.
|
||||
@param[in] SetVariableStatus Authoritative MM variable service result.
|
||||
**/
|
||||
VOID
|
||||
VariableRuntimeHookPostSetVariable (
|
||||
IN BOOLEAN HookInvoked,
|
||||
IN EFI_STATUS SetVariableStatus
|
||||
)
|
||||
{
|
||||
if (!HookInvoked) {
|
||||
return;
|
||||
}
|
||||
|
||||
mPostSetVariable (SetVariableStatus);
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/** @file
|
||||
Internal support for the optional VariableSmmRuntimeDxe hook protocol.
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Protocol/VariableSmmRuntimeDxeHook.h>
|
||||
|
||||
/**
|
||||
Discovers the first valid variable runtime hook provider and registers for
|
||||
notification if a provider is not yet available.
|
||||
|
||||
@retval EFI_SUCCESS Discovery was initialized or a provider was cached.
|
||||
@retval Others Event or protocol notification registration failed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
VariableRuntimeHookInitialize (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Stops variable runtime hook provider discovery and closes discovery events.
|
||||
**/
|
||||
VOID
|
||||
VariableRuntimeHookStopDiscovery (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Converts cached variable runtime hook callback pointers to virtual addresses.
|
||||
**/
|
||||
VOID
|
||||
VariableRuntimeHookConvertPointers (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Invokes the cached pre-hook for an OS runtime SetVariable() request.
|
||||
|
||||
@param[in] VariableName Name of the variable.
|
||||
@param[in] VendorGuid Variable vendor GUID.
|
||||
@param[in] Attributes Variable attributes.
|
||||
@param[in] DataSize Size of Data in bytes.
|
||||
@param[in] Data Variable data.
|
||||
@param[out] HookInvoked TRUE if the pre-hook returned success.
|
||||
|
||||
@retval EFI_SUCCESS Continue with MM communication.
|
||||
@retval Others The pre-hook rejected or deferred the operation.
|
||||
**/
|
||||
EFI_STATUS
|
||||
VariableRuntimeHookPreSetVariable (
|
||||
IN CONST CHAR16 *VariableName,
|
||||
IN CONST EFI_GUID *VendorGuid,
|
||||
IN UINT32 Attributes,
|
||||
IN UINTN DataSize,
|
||||
IN CONST VOID *Data,
|
||||
OUT BOOLEAN *HookInvoked
|
||||
);
|
||||
|
||||
/**
|
||||
Invokes the cached post-hook after MM communication completes.
|
||||
|
||||
@param[in] HookInvoked TRUE if the pre-hook returned success.
|
||||
@param[in] SetVariableStatus Authoritative MM variable service result.
|
||||
**/
|
||||
VOID
|
||||
VariableRuntimeHookPostSetVariable (
|
||||
IN BOOLEAN HookInvoked,
|
||||
IN EFI_STATUS SetVariableStatus
|
||||
);
|
||||
Loading…
Add table
Add a link
Reference in a new issue