summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStar Zeng <star.zeng@intel.com>2016-05-25 13:11:17 +0800
committerHao Wu <hao.a.wu@intel.com>2016-07-06 16:43:15 +0800
commit4b821a24c3c854e3cf43241a4663bd5ae9e47511 (patch)
treea488a8912c58f7514a9ca9b3558f76b8635fc5b3
parent03c41ca1a3308766e3d4aa8e30f1b7bb18ea45a4 (diff)
downloadedk2-platforms-4b821a24c3c854e3cf43241a4663bd5ae9e47511.tar.xz
MdeModulePkg DxeS3BootScriptLib: Add DESTRUCTOR S3BootScriptLibDeinitialize
PiDxeS3BootScriptLib has a constructor S3BootScriptLibInitialize() that registers ready-to-lock callback S3BootScriptSmmEventCallBack() and several more. The library is linked to SMM modules. If the module entry-point function returns error (because of lack of resources, unsupported, whatever), the module will be unloaded and the notify callback pointers will point to undefined memory. On ready-to-lock exception occurs when calling S3BootScriptSmmEventCallBack(), and probably all the other callbacks registered by the constructor would also cause exception. This patch is to implement library Destructor to free the resources allocated by S3BootScriptLibInitialize() and unregister callbacks. Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Laszlo Ersek <lersek@redhat.com> (cherry picked from commit cfd79783d603bb2db98ffa0a370bea572724d51c)
-rw-r--r--MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c155
-rw-r--r--MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf3
2 files changed, 124 insertions, 34 deletions
diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
index e7d2a2492e..f6de986e08 100644
--- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
+++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c
@@ -1,7 +1,7 @@
/** @file
- Save the S3 data to S3 boot script.
-
- Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+ Save the S3 data to S3 boot script.
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -124,6 +124,14 @@ EFI_GUID mBootScriptSmmPrivateDataGuid = {
0x627ee2da, 0x3bf9, 0x439b, { 0x92, 0x9f, 0x2e, 0xe, 0x6e, 0x9d, 0xba, 0x62 }
};
+EFI_EVENT mEventDxeSmmReadyToLock = NULL;
+VOID *mRegistrationSmmExitBootServices = NULL;
+VOID *mRegistrationSmmLegacyBoot = NULL;
+VOID *mRegistrationSmmReadyToLock = NULL;
+BOOLEAN mS3BootScriptTableAllocated = FALSE;
+BOOLEAN mS3BootScriptTableSmmAllocated = FALSE;
+EFI_SMM_SYSTEM_TABLE2 *mSmst = NULL;
+
/**
This is an internal function to add a terminate node the entry, recalculate the table
length and fill into the table.
@@ -417,8 +425,8 @@ S3BootScriptSmmAtRuntimeCallBack (
@param ImageHandle The firmware allocated handle for the EFI image.
@param SystemTable A pointer to the EFI System Table.
- @retval RETURN_SUCCESS Allocate the global memory space to store S3 boot script table private data
- @retval RETURN_OUT_OF_RESOURCES No enough memory to allocated.
+ @retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS.
+
**/
RETURN_STATUS
EFIAPI
@@ -433,9 +441,7 @@ S3BootScriptLibInitialize (
VOID *Registration;
EFI_SMM_BASE2_PROTOCOL *SmmBase2;
BOOLEAN InSmm;
- EFI_SMM_SYSTEM_TABLE2 *Smst;
EFI_PHYSICAL_ADDRESS Buffer;
- EFI_EVENT Event;
S3TablePtr = (SCRIPT_TABLE_PRIVATE_DATA*)(UINTN)PcdGet64(PcdS3BootScriptTablePrivateDataPtr);
//
@@ -449,25 +455,24 @@ S3BootScriptLibInitialize (
EFI_SIZE_TO_PAGES(sizeof(SCRIPT_TABLE_PRIVATE_DATA)),
&Buffer
);
- if (EFI_ERROR (Status)) {
- return RETURN_OUT_OF_RESOURCES;
- }
+ ASSERT_EFI_ERROR (Status);
+ mS3BootScriptTableAllocated = TRUE;
S3TablePtr = (VOID *) (UINTN) Buffer;
Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, (UINT64) (UINTN)S3TablePtr);
ASSERT_EFI_ERROR (Status);
- ZeroMem (S3TablePtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA));
+ ZeroMem (S3TablePtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA));
//
// Create event to notify the library system enter the SmmLocked phase.
//
- Event = EfiCreateProtocolNotifyEvent (
- &gEfiDxeSmmReadyToLockProtocolGuid,
- TPL_CALLBACK,
- S3BootScriptEventCallBack,
- NULL,
- &Registration
- );
- ASSERT (Event != NULL);
+ mEventDxeSmmReadyToLock = EfiCreateProtocolNotifyEvent (
+ &gEfiDxeSmmReadyToLockProtocolGuid,
+ TPL_CALLBACK,
+ S3BootScriptEventCallBack,
+ NULL,
+ &Registration
+ );
+ ASSERT (mEventDxeSmmReadyToLock != NULL);
}
mS3BootScriptTablePtr = S3TablePtr;
@@ -488,7 +493,7 @@ S3BootScriptLibInitialize (
//
// Good, we are in SMM
//
- Status = SmmBase2->GetSmstLocation (SmmBase2, &Smst);
+ Status = SmmBase2->GetSmstLocation (SmmBase2, &mSmst);
if (EFI_ERROR (Status)) {
return RETURN_SUCCESS;
}
@@ -498,14 +503,13 @@ S3BootScriptLibInitialize (
// The Boot script private data in SMM is not be initialized. create it
//
if (S3TableSmmPtr == 0) {
- Status = Smst->SmmAllocatePool (
+ Status = mSmst->SmmAllocatePool (
EfiRuntimeServicesData,
sizeof(SCRIPT_TABLE_PRIVATE_DATA),
(VOID **) &S3TableSmmPtr
);
- if (EFI_ERROR (Status)) {
- return RETURN_OUT_OF_RESOURCES;
- }
+ ASSERT_EFI_ERROR (Status);
+ mS3BootScriptTableSmmAllocated = TRUE;
Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, (UINT64) (UINTN)S3TableSmmPtr);
ASSERT_EFI_ERROR (Status);
@@ -514,19 +518,17 @@ S3BootScriptLibInitialize (
//
// Register SmmExitBootServices and SmmLegacyBoot notification.
//
- Registration = NULL;
- Status = Smst->SmmRegisterProtocolNotify (
+ Status = mSmst->SmmRegisterProtocolNotify (
&gEdkiiSmmExitBootServicesProtocolGuid,
S3BootScriptSmmAtRuntimeCallBack,
- &Registration
+ &mRegistrationSmmExitBootServices
);
ASSERT_EFI_ERROR (Status);
- Registration = NULL;
- Status = Smst->SmmRegisterProtocolNotify (
+ Status = mSmst->SmmRegisterProtocolNotify (
&gEdkiiSmmLegacyBootProtocolGuid,
S3BootScriptSmmAtRuntimeCallBack,
- &Registration
+ &mRegistrationSmmLegacyBoot
);
ASSERT_EFI_ERROR (Status);
}
@@ -535,16 +537,103 @@ S3BootScriptLibInitialize (
//
// Register SmmReadyToLock notification.
//
- Registration = NULL;
- Status = Smst->SmmRegisterProtocolNotify (
+ Status = mSmst->SmmRegisterProtocolNotify (
&gEfiSmmReadyToLockProtocolGuid,
S3BootScriptSmmEventCallBack,
- &Registration
+ &mRegistrationSmmReadyToLock
);
ASSERT_EFI_ERROR (Status);
return RETURN_SUCCESS;
}
+
+/**
+ Library Destructor to free the resources allocated by
+ S3BootScriptLibInitialize() and unregister callbacks.
+
+ NOTICE: The destructor doesn't support unloading as a separate action, and it
+ only supports unloading if the containing driver's entry point function fails.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval RETURN_SUCCESS The destructor always returns RETURN_SUCCESS.
+
+**/
+RETURN_STATUS
+EFIAPI
+S3BootScriptLibDeinitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "%a() in %a module\n", __FUNCTION__, gEfiCallerBaseName));
+
+ if (mEventDxeSmmReadyToLock != NULL) {
+ //
+ // Close the DxeSmmReadyToLock event.
+ //
+ Status = gBS->CloseEvent (mEventDxeSmmReadyToLock);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (mSmst != NULL) {
+ if (mRegistrationSmmExitBootServices != NULL) {
+ //
+ // Unregister SmmExitBootServices notification.
+ //
+ Status = mSmst->SmmRegisterProtocolNotify (
+ &gEdkiiSmmExitBootServicesProtocolGuid,
+ NULL,
+ &mRegistrationSmmExitBootServices
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ if (mRegistrationSmmLegacyBoot != NULL) {
+ //
+ // Unregister SmmLegacyBoot notification.
+ //
+ Status = mSmst->SmmRegisterProtocolNotify (
+ &gEdkiiSmmLegacyBootProtocolGuid,
+ NULL,
+ &mRegistrationSmmLegacyBoot
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ if (mRegistrationSmmReadyToLock != NULL) {
+ //
+ // Unregister SmmReadyToLock notification.
+ //
+ Status = mSmst->SmmRegisterProtocolNotify (
+ &gEfiSmmReadyToLockProtocolGuid,
+ NULL,
+ &mRegistrationSmmReadyToLock
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ //
+ // Free the resources allocated and set PCDs to 0.
+ //
+ if (mS3BootScriptTableAllocated) {
+ Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) mS3BootScriptTablePtr, EFI_SIZE_TO_PAGES(sizeof(SCRIPT_TABLE_PRIVATE_DATA)));
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, 0);
+ ASSERT_EFI_ERROR (Status);
+ }
+ if (mS3BootScriptTableSmmAllocated) {
+ Status = mSmst->SmmFreePool (mS3BootScriptTableSmmPtr);
+ ASSERT_EFI_ERROR (Status);
+ Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, 0);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return RETURN_SUCCESS;
+}
+
/**
To get the start address from which a new boot time s3 boot script entry will write into.
If the table is not exist, the functio will first allocate a buffer for the table
diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf b/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
index 6b7540a5ea..de314db479 100644
--- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
@@ -1,7 +1,7 @@
## @file
# DXE S3 boot script Library.
#
-# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are
# licensed and made available under the terms and conditions of the BSD License
@@ -24,6 +24,7 @@
CONSTRUCTOR = S3BootScriptLibInitialize
+ DESTRUCTOR = S3BootScriptLibDeinitialize
#
# The following information is for reference only and not required by the build tools.