summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/Variable
diff options
context:
space:
mode:
authorlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>2013-01-08 02:07:14 +0000
committerlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>2013-01-08 02:07:14 +0000
commit6ed1ec5946efbfa78c14d21374525323d54d5462 (patch)
tree12446c61396ab7a431310475a5605c7aeac9fedd /MdeModulePkg/Universal/Variable
parent48c8b6a299918612436e84ab22b55be6b88a90a2 (diff)
Add the TPL raise/restore code for VariableSmmRuntimeDxe to avoid variable services reentry.
Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14038 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal/Variable')
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c94
1 files changed, 78 insertions, 16 deletions
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
index 442fe1dad..e4d3aca19 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
@@ -4,7 +4,7 @@
and volatile storage space and install variable architecture protocol
based on SMM variable module.
-Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2012, 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
which accompanies this distribution. The full text of the license may be found at
@@ -42,7 +42,51 @@ EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;
UINT8 *mVariableBuffer = NULL;
UINT8 *mVariableBufferPhysical = NULL;
UINTN mVariableBufferSize;
+EFI_LOCK mVariableServicesLock;
+/**
+ Acquires lock only at boot time. Simply returns at runtime.
+
+ This is a temperary function that will be removed when
+ EfiAcquireLock() in UefiLib can handle the call in UEFI
+ Runtimer driver in RT phase.
+ It calls EfiAcquireLock() at boot time, and simply returns
+ at runtime.
+
+ @param Lock A pointer to the lock to acquire.
+
+**/
+VOID
+AcquireLockOnlyAtBootTime (
+ IN EFI_LOCK *Lock
+ )
+{
+ if (!EfiAtRuntime ()) {
+ EfiAcquireLock (Lock);
+ }
+}
+
+/**
+ Releases lock only at boot time. Simply returns at runtime.
+
+ This is a temperary function which will be removed when
+ EfiReleaseLock() in UefiLib can handle the call in UEFI
+ Runtimer driver in RT phase.
+ It calls EfiReleaseLock() at boot time and simply returns
+ at runtime.
+
+ @param Lock A pointer to the lock to release.
+
+**/
+VOID
+ReleaseLockOnlyAtBootTime (
+ IN EFI_LOCK *Lock
+ )
+{
+ if (!EfiAtRuntime ()) {
+ EfiReleaseLock (Lock);
+ }
+}
/**
Initialize the communicate buffer using DataSize and Function.
@@ -153,15 +197,17 @@ RuntimeServiceGetVariable (
if ((*DataSize != 0) && (Data == NULL)) {
return EFI_INVALID_PARAMETER;
}
-
+
+ AcquireLockOnlyAtBootTime(&mVariableServicesLock);
+
//
// Init the communicate buffer. The buffer data size is:
- // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize + DataSize.
+ // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.
//
PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + StrSize (VariableName) + *DataSize;
Status = InitCommunicateBuffer ((VOID **)&SmmVariableHeader, PayloadSize, SMM_VARIABLE_FUNCTION_GET_VARIABLE);
if (EFI_ERROR (Status)) {
- return Status;
+ goto Done;
}
ASSERT (SmmVariableHeader != NULL);
@@ -189,11 +235,13 @@ RuntimeServiceGetVariable (
}
if (EFI_ERROR (Status)) {
- return Status;
+ goto Done;
}
CopyMem (Data, (UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize, SmmVariableHeader->DataSize);
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
return Status;
}
@@ -226,7 +274,9 @@ RuntimeServiceGetNextVariableName (
if (VariableNameSize == NULL || VariableName == NULL || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
-
+
+ AcquireLockOnlyAtBootTime(&mVariableServicesLock);
+
//
// Init the communicate buffer. The buffer data size is:
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.
@@ -234,7 +284,7 @@ RuntimeServiceGetNextVariableName (
PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name) + *VariableNameSize;
Status = InitCommunicateBuffer ((VOID **)&SmmGetNextVariableName, PayloadSize, SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME);
if (EFI_ERROR (Status)) {
- return Status;
+ goto Done;
}
ASSERT (SmmGetNextVariableName != NULL);
@@ -252,12 +302,14 @@ RuntimeServiceGetNextVariableName (
//
*VariableNameSize = SmmGetNextVariableName->NameSize;
if (EFI_ERROR (Status)) {
- return Status;
+ goto Done;
}
CopyGuid (VendorGuid, &SmmGetNextVariableName->Guid);
CopyMem (VariableName, SmmGetNextVariableName->Name, SmmGetNextVariableName->NameSize);
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
return Status;
}
@@ -302,7 +354,9 @@ RuntimeServiceSetVariable (
if (DataSize != 0 && Data == NULL) {
return EFI_INVALID_PARAMETER;
}
-
+
+ AcquireLockOnlyAtBootTime(&mVariableServicesLock);
+
//
// Init the communicate buffer. The buffer data size is:
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.
@@ -310,7 +364,7 @@ RuntimeServiceSetVariable (
PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) + StrSize (VariableName) + DataSize;
Status = InitCommunicateBuffer ((VOID **)&SmmVariableHeader, PayloadSize, SMM_VARIABLE_FUNCTION_SET_VARIABLE);
if (EFI_ERROR (Status)) {
- return Status;
+ goto Done;
}
ASSERT (SmmVariableHeader != NULL);
@@ -325,7 +379,9 @@ RuntimeServiceSetVariable (
// Send data to SMM.
//
Status = SendCommunicateBuffer (PayloadSize);
-
+
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
return Status;
}
@@ -363,7 +419,9 @@ RuntimeServiceQueryVariableInfo (
if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
return EFI_INVALID_PARAMETER;
}
-
+
+ AcquireLockOnlyAtBootTime(&mVariableServicesLock);
+
//
// Init the communicate buffer. The buffer data size is:
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize;
@@ -371,7 +429,7 @@ RuntimeServiceQueryVariableInfo (
PayloadSize = sizeof (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO);
Status = InitCommunicateBuffer ((VOID **)&SmmQueryVariableInfo, PayloadSize, SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO);
if (EFI_ERROR (Status)) {
- return Status;
+ goto Done;
}
ASSERT (SmmQueryVariableInfo != NULL);
@@ -382,7 +440,7 @@ RuntimeServiceQueryVariableInfo (
//
Status = SendCommunicateBuffer (PayloadSize);
if (EFI_ERROR (Status)) {
- return Status;
+ goto Done;
}
//
@@ -391,7 +449,9 @@ RuntimeServiceQueryVariableInfo (
*MaximumVariableSize = SmmQueryVariableInfo->MaximumVariableSize;
*MaximumVariableStorageSize = SmmQueryVariableInfo->MaximumVariableStorageSize;
*RemainingVariableStorageSize = SmmQueryVariableInfo->RemainingVariableStorageSize;
-
+
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
return EFI_SUCCESS;
}
@@ -589,7 +649,9 @@ VariableSmmRuntimeInitialize (
VOID *SmmVariableWriteRegistration;
EFI_EVENT OnReadyToBootEvent;
EFI_EVENT ExitBootServiceEvent;
-
+
+ EfiInitializeLock (&mVariableServicesLock, TPL_NOTIFY);
+
//
// Smm variable service is ready
//