Skip to content

Commit

Permalink
MdeModulePkg/Variable: Init var policy after SMM variable is ready (#…
Browse files Browse the repository at this point in the history
…1269)

## Description

On a MM system, the main UEFI variable logic resides in MMRAM. In that
case, the variable policy logic in `VarCheckPolicyLib`, such as
`VarCheckPolicyLibStandaloneMm` is linked against the MM driver also in
that case `VariableStandaloneMm`.

The MM variable driver indicates its presence to the RT DXE driver via
`gEfiSmmVariableProtocolGuid` to indicate variable read support is
available from MM. This triggers installation of the variable
architectural protocol in DXE.

Today, variable policy is initialized by calling
`VariablePolicySmmDxeMain()` in `VariableSmmRuntimeInitialize()`. In
turn, this installs `gEdkiiVariablePolicyProtocolGuid`. Functions in
`gEdkiiVariablePolicyProtocolGuid` may trigger MMIs. However, it is
possible that the MM variable driver which is linked against the code
with the variable policy MMI handlers (i.e. `VarCheckPolicyLib`) is not
loaded yet.

Therefore, this change moves invocation of `VariablePolicySmmDxeMain()`
to `SmmVariableReady()` which is called on installation of
`gEfiSmmVariableProtocolGuid` indicating variable MM services are ready.
`gEdkiiVariablePolicyProtocolGuid` is still installed prior to the
variable architectural protocol being installed.

- [x] Impacts functionality?
- [ ] Impacts security?
- [ ] Breaking change?
- [ ] Includes tests?
- [ ] Includes documentation?
- [ ] Backport to release branch?

## How This Was Tested

- Verify variable policy is initialized as expected on QEMU Q35/SBSA and
a physical Intel system.
- Check that the variable image handle passed to
`VariablePolicySmmDxeMain()` is correct.

## Integration Instructions

N/A - Some drivers may dispatch differently if they depend on
`gEdkiiVariablePolicyProtocolGuid`. However, this is not considered
breaking as that is an inherent expectation in dispatch based on
dependency expressions.

Signed-off-by: Michael Kubacki <[email protected]>
  • Loading branch information
makubacki authored Feb 7, 2025
1 parent c75e4c8 commit 653e31e
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ VariablePolicyVirtualAddressCallback (
The driver's entry point.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
// @param[in] SystemTable A pointer to the EFI System Table. // MU_CHANGE - Initialize var policy after SMM Variable is ready
@retval EFI_SUCCESS The entry point executed successfully.
@retval other Some error occured when executing this entry point.
Expand All @@ -822,8 +822,8 @@ VariablePolicyVirtualAddressCallback (
EFI_STATUS
EFIAPI
VariablePolicySmmDxeMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
IN EFI_HANDLE ImageHandle // MU_CHANGE - Initialize var policy after SMM Variable is ready
// IN EFI_SYSTEM_TABLE *SystemTable // MU_CHANGE - Initialize var policy after SMM Variable is ready
)
{
EFI_STATUS Status;
Expand Down
23 changes: 18 additions & 5 deletions MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ EDKII_VAR_CHECK_PROTOCOL mVarCheck;
EFI_STATUS
EFIAPI
VariablePolicySmmDxeMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
IN EFI_HANDLE ImageHandle // MU_CHANGE - Initialize var policy after SMM Variable is ready
// IN EFI_SYSTEM_TABLE *SystemTable // MU_CHANGE - Initialize var policy after SMM Variable is ready
);

/**
Expand Down Expand Up @@ -1692,6 +1692,7 @@ SmmVariableReady (
)
{
EFI_STATUS Status;
EFI_HANDLE VariablePolicyHandle; // MU_CHANGE - Initialize var policy after SMM Variable is ready

Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable);
if (EFI_ERROR (Status)) {
Expand Down Expand Up @@ -1758,6 +1759,16 @@ SmmVariableReady (
gRT->SetVariable = RuntimeServiceSetVariable;
gRT->QueryVariableInfo = RuntimeServiceQueryVariableInfo;

// MU_CHANGE [BEGIN] - Initialize var policy after SMM Variable is ready
VariablePolicyHandle = (Context != NULL) ? Context : mHandle;
if (Context == NULL) {
DEBUG ((DEBUG_ERROR, "Variable policy was installed on a handle other than the variable image handle.\n"));
}

// Initialize the VariablePolicy protocol and engine.
VariablePolicySmmDxeMain (VariablePolicyHandle);
// MU_CHANGE [END] - Initialize var policy after SMM Variable is ready

//
// Install the Variable Architectural Protocol on a new handle.
//
Expand Down Expand Up @@ -1868,7 +1879,7 @@ VariableSmmRuntimeInitialize (
&gEfiSmmVariableProtocolGuid,
TPL_CALLBACK,
SmmVariableReady,
NULL,
ImageHandle, // MU_CHANGE - Initialize var policy after SMM Variable is ready
&SmmVariableRegistration
);

Expand Down Expand Up @@ -1930,8 +1941,10 @@ VariableSmmRuntimeInitialize (
&mVirtualAddressChangeEvent
);

// Initialize the VariablePolicy protocol and engine.
VariablePolicySmmDxeMain (ImageHandle, SystemTable);
// MU_CHANGE [BEGIN] - Initialize var policy after SMM Variable is ready
// // Initialize the VariablePolicy protocol and engine.
// VariablePolicySmmDxeMain (ImageHandle, SystemTable);
// MU_CHANGE [END] - Initialize var policy after SMM Variable is ready

return EFI_SUCCESS;
}

0 comments on commit 653e31e

Please sign in to comment.