Revision: 14038
          http://edk2.svn.sourceforge.net/edk2/?rev=14038&view=rev
Author:   lzeng14
Date:     2013-01-08 02:07:14 +0000 (Tue, 08 Jan 2013)
Log Message:
-----------
Add the TPL raise/restore code for VariableSmmRuntimeDxe to avoid variable 
services reentry.

Signed-off-by: Star Zeng <[email protected]>
Reviewed-by: Jiewen Yao <[email protected]>

Modified Paths:
--------------
    
trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
    
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c

Modified: 
trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
===================================================================
--- 
trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c   
    2013-01-07 07:12:19 UTC (rev 14037)
+++ 
trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c   
    2013-01-08 02:07:14 UTC (rev 14038)
@@ -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,9 +42,53 @@
 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.
 
   The communicate size is: SMM_COMMUNICATE_HEADER_SIZE + 
SMM_VARIABLE_COMMUNICATE_HEADER_SIZE +
@@ -153,15 +197,17 @@
   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 @@
   }
 
   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 @@
   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 @@
   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 @@
   //
   *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 @@
   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 @@
   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 @@
   // Send data to SMM.
   //
   Status = SendCommunicateBuffer (PayloadSize);
- 
+
+Done:
+  ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
   return Status;
 }
 
@@ -363,7 +419,9 @@
   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 @@
   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 @@
   //
   Status = SendCommunicateBuffer (PayloadSize);
   if (EFI_ERROR (Status)) {
-    return Status;
+    goto Done;
   }
 
   //
@@ -391,7 +449,9 @@
   *MaximumVariableSize          = SmmQueryVariableInfo->MaximumVariableSize;
   *MaximumVariableStorageSize   = 
SmmQueryVariableInfo->MaximumVariableStorageSize;
   *RemainingVariableStorageSize = 
SmmQueryVariableInfo->RemainingVariableStorageSize; 
- 
+
+Done:
+  ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
   return EFI_SUCCESS;
 }
 
@@ -589,7 +649,9 @@
   VOID                                      *SmmVariableWriteRegistration;
   EFI_EVENT                                 OnReadyToBootEvent;
   EFI_EVENT                                 ExitBootServiceEvent;
-  
+
+  EfiInitializeLock (&mVariableServicesLock, TPL_NOTIFY);
+
   //
   // Smm variable service is ready
   //

Modified: 
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
===================================================================
--- 
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c 
    2013-01-07 07:12:19 UTC (rev 14037)
+++ 
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c 
    2013-01-08 02:07:14 UTC (rev 14038)
@@ -52,9 +52,53 @@
 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.
 
   The communicate size is: SMM_COMMUNICATE_HEADER_SIZE + 
SMM_VARIABLE_COMMUNICATE_HEADER_SIZE +
@@ -169,15 +213,17 @@
   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);
 
@@ -205,11 +251,13 @@
   }
 
   if (EFI_ERROR (Status)) {
-    return Status;
+    goto Done;
   }
 
   CopyMem (Data, (UINT8 *)SmmVariableHeader->Name + 
SmmVariableHeader->NameSize, SmmVariableHeader->DataSize);
 
+Done:
+  ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
   return Status;
 }
 
@@ -242,7 +290,9 @@
   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.
@@ -250,7 +300,7 @@
   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);
 
@@ -268,12 +318,14 @@
   //
   *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;
 }
 
@@ -321,7 +373,9 @@
   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.
@@ -329,7 +383,7 @@
   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);
 
@@ -344,7 +398,9 @@
   // Send data to SMM.
   //
   Status = SendCommunicateBuffer (PayloadSize);
- 
+
+Done:
+  ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
   return Status;
 }
 
@@ -382,7 +438,9 @@
   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;
@@ -390,7 +448,7 @@
   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);
 
@@ -401,7 +459,7 @@
   //
   Status = SendCommunicateBuffer (PayloadSize);
   if (EFI_ERROR (Status)) {
-    return Status;
+    goto Done;
   }
 
   //
@@ -410,7 +468,9 @@
   *MaximumVariableSize          = SmmQueryVariableInfo->MaximumVariableSize;
   *MaximumVariableStorageSize   = 
SmmQueryVariableInfo->MaximumVariableStorageSize;
   *RemainingVariableStorageSize = 
SmmQueryVariableInfo->RemainingVariableStorageSize; 
- 
+
+Done:
+  ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
   return EFI_SUCCESS;
 }
 
@@ -608,7 +668,9 @@
   VOID                                      *SmmVariableWriteRegistration;
   EFI_EVENT                                 OnReadyToBootEvent;
   EFI_EVENT                                 ExitBootServiceEvent;
-  
+
+  EfiInitializeLock (&mVariableServicesLock, TPL_NOTIFY);
+
   //
   // Smm variable service is ready
   //

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Master SQL Server Development, Administration, T-SQL, SSAS, SSIS, SSRS
and more. Get SQL Server skills now (including 2012) with LearnDevNow -
200+ hours of step-by-step video tutorials by Microsoft MVPs and experts.
SALE $99.99 this month only - learn more at:
http://p.sf.net/sfu/learnmore_122512
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to