diff --git a/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c b/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
index 623f8a978c..97823265f9 100644
--- a/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
+++ b/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
@@ -6,7 +6,7 @@
to log performance data. If both SMM PerformanceEx and Performance Protocol are not available, it does not log any
performance information.
- Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -23,6 +23,36 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
// The cached SMM Performance Protocol and SMM PerformanceEx Protocol interface.
EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL *mPerformanceMeasurement = NULL;
BOOLEAN mPerformanceMeasurementEnabled;
+VOID *mPerformanceLibExitBootServicesRegistration;
+
+/**
+ This is the Event call back function is triggered in SMM to notify the Library
+ the system is entering runtime phase.
+
+ @param[in] Protocol Points to the protocol's unique identifier
+ @param[in] Interface Points to the interface instance
+ @param[in] Handle The handle on which the interface was installed
+
+ @retval EFI_SUCCESS SmmAtRuntimeCallBack runs successfully
+ **/
+EFI_STATUS
+EFIAPI
+SmmPerformanceLibExitBootServicesCallback (
+ IN CONST EFI_GUID *Protocol,
+ IN VOID *Interface,
+ IN EFI_HANDLE Handle
+ )
+{
+ //
+ // Disable performance measurement after ExitBootServices because
+ // 1. Performance measurement might impact SMI latency at runtime;
+ // 2. Performance log is copied to non SMRAM at ReadyToBoot so runtime performance
+ // log is not useful.
+ //
+ mPerformanceMeasurementEnabled = FALSE;
+
+ return EFI_SUCCESS;
+}
/**
The constructor function initializes the Performance Measurement Enable flag
@@ -40,9 +70,48 @@ SmmPerformanceLibConstructor (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
+ EFI_STATUS Status;
+
mPerformanceMeasurementEnabled = (BOOLEAN)((PcdGet8 (PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
- return EFI_SUCCESS;
+ Status = gSmst->SmmRegisterProtocolNotify (
+ &gEdkiiSmmExitBootServicesProtocolGuid,
+ SmmPerformanceLibExitBootServicesCallback,
+ &mPerformanceLibExitBootServicesRegistration
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ The destructor function frees resources allocated by constructor.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The destructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+SmmPerformanceLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Unregister SmmExitBootServices notification.
+ //
+ Status = gSmst->SmmRegisterProtocolNotify (
+ &gEdkiiSmmExitBootServicesProtocolGuid,
+ NULL,
+ &mPerformanceLibExitBootServicesRegistration
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
}
/**
diff --git a/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf b/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf
index d79cd5c8da..002462f5ca 100644
--- a/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf
+++ b/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf
@@ -21,6 +21,7 @@
LIBRARY_CLASS = PerformanceLib|DXE_SMM_DRIVER
CONSTRUCTOR = SmmPerformanceLibConstructor
+ DESTRUCTOR = SmmPerformanceLibDestructor
#
# The following information is for reference only and not required by the build tools.
@@ -46,5 +47,8 @@
[Guids]
gEdkiiSmmPerformanceMeasurementProtocolGuid ## SOMETIMES_CONSUMES ## UNDEFINED # Locate protocol
+[Protocols]
+ gEdkiiSmmExitBootServicesProtocolGuid ## CONSUMES
+
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask ## CONSUMES