Revision: 14822
          http://sourceforge.net/p/edk2/code/14822
Author:   lzeng14
Date:     2013-11-04 03:13:54 +0000 (Mon, 04 Nov 2013)
Log Message:
-----------
MdeModulePkg and SecurityPkg Variable: Enhance code to use the new variable 
data instead of old variable data when variable reclaim.

It can fix the potential failure to return EFI_OUT_OF_RESOURCES of the second 
variable set of large variable.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <[email protected]>
Reviewed-by: Liming Gao <[email protected]>

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

Modified: trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c    
2013-11-01 17:01:23 UTC (rev 14821)
+++ trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c    
2013-11-04 03:13:54 UTC (rev 14822)
@@ -566,7 +566,8 @@
   @param IsVolatile              The variable store is volatile or not;
                                  if it is non-volatile, need FTW.
   @param UpdatingPtrTrack        Pointer to updating variable pointer track 
structure.
-  @param ReclaimAnyway           If TRUE, do reclaim anyway.
+  @param NewVariable             Pointer to new variable.
+  @param NewVariableSize         New variable size.
 
   @return EFI_OUT_OF_RESOURCES
   @return EFI_SUCCESS
@@ -579,7 +580,8 @@
   OUT UINTN                 *LastVariableOffset,
   IN  BOOLEAN               IsVolatile,
   IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack,
-  IN  BOOLEAN               ReclaimAnyway
+  IN  VARIABLE_HEADER       *NewVariable,
+  IN  UINTN                 NewVariableSize
   )
 {
   VARIABLE_HEADER       *Variable;
@@ -590,27 +592,24 @@
   UINT8                 *ValidBuffer;
   UINTN                 MaximumBufferSize;
   UINTN                 VariableSize;
-  UINTN                 VariableNameSize;
-  UINTN                 UpdatingVariableNameSize;
   UINTN                 NameSize;
   UINT8                 *CurrPtr;
   VOID                  *Point0;
   VOID                  *Point1;
   BOOLEAN               FoundAdded;
   EFI_STATUS            Status;
-  CHAR16                *VariableNamePtr;
-  CHAR16                *UpdatingVariableNamePtr;
   UINTN                 CommonVariableTotalSize;
   UINTN                 HwErrVariableTotalSize;
-  BOOLEAN               NeedDoReclaim;
   VARIABLE_HEADER       *UpdatingVariable;
+  VARIABLE_HEADER       *UpdatingInDeletedTransition;
 
   UpdatingVariable = NULL;
+  UpdatingInDeletedTransition = NULL;
   if (UpdatingPtrTrack != NULL) {
     UpdatingVariable = UpdatingPtrTrack->CurrPtr;
+    UpdatingInDeletedTransition = UpdatingPtrTrack->InDeletedTransitionPtr;
   }
 
-  NeedDoReclaim = FALSE;
   VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
 
   CommonVariableTotalSize = 0;
@@ -624,21 +623,22 @@
 
   while (IsValidVariableHeader (Variable)) {
     NextVariable = GetNextVariablePtr (Variable);
-    if (Variable->State == VAR_ADDED || 
-        Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
+    if ((Variable->State == VAR_ADDED || Variable->State == 
(VAR_IN_DELETED_TRANSITION & VAR_ADDED)) &&
+        Variable != UpdatingVariable &&
+        Variable != UpdatingInDeletedTransition
        ) {
       VariableSize = (UINTN) NextVariable - (UINTN) Variable;
       MaximumBufferSize += VariableSize;
-    } else {
-      NeedDoReclaim = TRUE;
     }
 
     Variable = NextVariable;
   }
 
-  if (!ReclaimAnyway && !NeedDoReclaim) {
-    DEBUG ((EFI_D_INFO, "Variable driver: no DELETED variable found, so no 
variable space could be reclaimed.\n"));
-    return EFI_SUCCESS;
+  if (NewVariable != NULL) {
+    //
+    // Add the new variable size.
+    //
+    MaximumBufferSize += NewVariableSize;
   }
 
   //
@@ -665,25 +665,7 @@
   Variable = GetStartPointer (VariableStoreHeader);
   while (IsValidVariableHeader (Variable)) {
     NextVariable = GetNextVariablePtr (Variable);
-    if (Variable->State == VAR_ADDED) {
-      if (UpdatingVariable != NULL) {
-        if (UpdatingVariable == Variable) {
-          Variable = NextVariable;
-          continue;
-        }
-
-        VariableNameSize         = NameSizeOfVariable(Variable);
-        UpdatingVariableNameSize = NameSizeOfVariable(UpdatingVariable);
-
-        VariableNamePtr         = GetVariableNamePtr (Variable);
-        UpdatingVariableNamePtr = GetVariableNamePtr (UpdatingVariable);
-        if (CompareGuid (&Variable->VendorGuid, &UpdatingVariable->VendorGuid) 
   &&
-            VariableNameSize == UpdatingVariableNameSize &&
-            CompareMem (VariableNamePtr, UpdatingVariableNamePtr, 
VariableNameSize) == 0 ) {
-          Variable = NextVariable;
-          continue;
-        }
-      }
+    if (Variable != UpdatingVariable && Variable->State == VAR_ADDED) {
       VariableSize = (UINTN) NextVariable - (UINTN) Variable;
       CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
       CurrPtr += VariableSize;
@@ -697,28 +679,12 @@
   }
 
   //
-  // Reinstall the variable being updated if it is not NULL.
-  //
-  if (UpdatingVariable != NULL) {
-    VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - 
(UINTN)UpdatingVariable;
-    CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize);
-    UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER 
*)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer 
((VARIABLE_STORE_HEADER *) ValidBuffer)));
-    UpdatingPtrTrack->InDeletedTransitionPtr = NULL;
-    CurrPtr += VariableSize;
-    if ((!IsVolatile) && ((UpdatingVariable->Attributes & 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
-        HwErrVariableTotalSize += VariableSize;
-    } else if ((!IsVolatile) && ((UpdatingVariable->Attributes & 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
-        CommonVariableTotalSize += VariableSize;
-    }
-  }
-
-  //
   // Reinstall all in delete transition variables.
   // 
-  Variable      = GetStartPointer (VariableStoreHeader);
+  Variable = GetStartPointer (VariableStoreHeader);
   while (IsValidVariableHeader (Variable)) {
     NextVariable = GetNextVariablePtr (Variable);
-    if (Variable != UpdatingVariable && Variable->State == 
(VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+    if (Variable != UpdatingVariable && Variable != 
UpdatingInDeletedTransition && Variable->State == (VAR_IN_DELETED_TRANSITION & 
VAR_ADDED)) {
 
       //
       // Buffer has cached all ADDED variable. 
@@ -762,12 +728,48 @@
     Variable = NextVariable;
   }
 
+  //
+  // Install the new variable if it is not NULL.
+  //
+  if (NewVariable != NULL) {
+    if ((UINTN) (CurrPtr - ValidBuffer) + NewVariableSize > 
VariableStoreHeader->Size) {
+      //
+      // No enough space to store the new variable.
+      //
+      Status = EFI_OUT_OF_RESOURCES;
+      goto Done;
+    }
+    if (!IsVolatile) {
+      if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+        HwErrVariableTotalSize += NewVariableSize;
+      } else if ((NewVariable->Attributes & 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+        CommonVariableTotalSize += NewVariableSize;
+      }
+      if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) ||
+          (CommonVariableTotalSize > VariableStoreHeader->Size - sizeof 
(VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize))) {
+        //
+        // No enough space to store the new variable by NV or NV+HR attribute.
+        //
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Done;
+      }
+    }
+
+    CopyMem (CurrPtr, (UINT8 *) NewVariable, NewVariableSize);
+    ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED;
+    if (UpdatingVariable != NULL) {
+      UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER 
*)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer 
((VARIABLE_STORE_HEADER *) ValidBuffer)));
+      UpdatingPtrTrack->InDeletedTransitionPtr = NULL;
+    }
+    CurrPtr += NewVariableSize;
+  }
+
   if (IsVolatile) {
     //
     // If volatile variable store, just copy valid buffer.
     //
     SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
-    CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - 
(UINT8 *) ValidBuffer));
+    CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - 
ValidBuffer));
     Status  = EFI_SUCCESS;
   } else {
     //
@@ -776,12 +778,12 @@
     Status = FtwVariableSpace (
               VariableBase,
               ValidBuffer,
-              (UINTN) (CurrPtr - (UINT8 *) ValidBuffer)
+              (UINTN) (CurrPtr - ValidBuffer)
               );
     CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, 
VariableStoreHeader->Size);
   }
   if (!EFI_ERROR (Status)) {
-    *LastVariableOffset = (UINTN) (CurrPtr - (UINT8 *) ValidBuffer);
+    *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
     if (!IsVolatile) {
       mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize;
       mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize;
@@ -801,6 +803,7 @@
     *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase;
   }
 
+Done:
   FreePool (ValidBuffer);
 
   return Status;
@@ -1706,27 +1709,22 @@
         goto Done;
       }
       //
-      // Perform garbage collection & reclaim operation.
+      // Perform garbage collection & reclaim operation, and integrate the new 
variable at the same time.
       //
       Status = Reclaim 
(mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, 
-                        &mVariableModuleGlobal->NonVolatileLastVariableOffset, 
FALSE, Variable, FALSE);
-      if (EFI_ERROR (Status)) {
-        goto Done;
+                        &mVariableModuleGlobal->NonVolatileLastVariableOffset, 
FALSE, Variable, NextVariable, HEADER_ALIGN (VarSize));
+      if (!EFI_ERROR (Status)) {
+        //
+        // The new variable has been integrated successfully during reclaiming.
+        //
+        if (Variable->CurrPtr != NULL) {
+          CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) 
CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) 
Variable->StartPtr));
+          CacheVariable->InDeletedTransitionPtr = NULL;
+        }
+        UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, 
FALSE, FALSE);
+        FlushHobVariableToFlash (VariableName, VendorGuid);
       }
-      //
-      // If still no enough space, return out of resources.
-      //
-      if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) 
-        && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > 
PcdGet32 (PcdHwErrStorageSize)))
-        || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) 
-        && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > 
NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 
(PcdHwErrStorageSize)))) {
-        Status = EFI_OUT_OF_RESOURCES;
-        goto Done;
-      }
-      if (Variable->CurrPtr != NULL) {
-        CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) 
CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) 
Variable->StartPtr));
-        CacheVariable->InDeletedTransitionPtr = NULL;
-      }
+      goto Done;
     }
     //
     // Four steps
@@ -1824,26 +1822,21 @@
     if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) 
>
         ((VARIABLE_STORE_HEADER *) ((UINTN) 
(mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size) {
       //
-      // Perform garbage collection & reclaim operation.
+      // Perform garbage collection & reclaim operation, and integrate the new 
variable at the same time.
       //
       Status = Reclaim 
(mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, 
-                          &mVariableModuleGlobal->VolatileLastVariableOffset, 
TRUE, Variable, FALSE);
-      if (EFI_ERROR (Status)) {
-        goto Done;
+                          &mVariableModuleGlobal->VolatileLastVariableOffset, 
TRUE, Variable, NextVariable, HEADER_ALIGN (VarSize));
+      if (!EFI_ERROR (Status)) {
+        //
+        // The new variable has been integrated successfully during reclaiming.
+        //
+        if (Variable->CurrPtr != NULL) {
+          CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) 
CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) 
Variable->StartPtr));
+          CacheVariable->InDeletedTransitionPtr = NULL;
+        }
+        UpdateVariableInfo (VariableName, VendorGuid, TRUE, FALSE, TRUE, 
FALSE, FALSE);
       }
-      //
-      // If still no enough space, return out of resources.
-      //
-      if ((UINT32) (VarSize + 
mVariableModuleGlobal->VolatileLastVariableOffset) >
-            ((VARIABLE_STORE_HEADER *) ((UINTN) 
(mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size
-            ) {
-        Status = EFI_OUT_OF_RESOURCES;
-        goto Done;
-      }
-      if (Variable->CurrPtr != NULL) {
-        CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) 
CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) 
Variable->StartPtr));
-        CacheVariable->InDeletedTransitionPtr = NULL;
-      }
+      goto Done;
     }
 
     NextVariable->State = VAR_ADDED;
@@ -2693,7 +2686,8 @@
             &mVariableModuleGlobal->NonVolatileLastVariableOffset,
             FALSE,
             NULL,
-            FALSE
+            NULL,
+            0
             );
     ASSERT_EFI_ERROR (Status);
   }
@@ -2963,7 +2957,8 @@
                  &mVariableModuleGlobal->NonVolatileLastVariableOffset,
                  FALSE,
                  NULL,
-                 TRUE
+                 NULL,
+                 0
                  );
       if (EFI_ERROR (Status)) {
         return Status;

Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c       
2013-11-01 17:01:23 UTC (rev 14821)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c       
2013-11-04 03:13:54 UTC (rev 14822)
@@ -531,7 +531,8 @@
                  &mVariableModuleGlobal->NonVolatileLastVariableOffset,
                  FALSE,
                  NULL,
-                 TRUE,
+                 NULL,
+                 0,
                  TRUE
                  );
       if (EFI_ERROR (Status)) {

Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c  
2013-11-01 17:01:23 UTC (rev 14821)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c  
2013-11-04 03:13:54 UTC (rev 14822)
@@ -731,11 +731,12 @@
   @param[in]      IsVolatile              The variable store is volatile or 
not;
                                           if it is non-volatile, need FTW.
   @param[in, out] UpdatingPtrTrack        Pointer to updating variable pointer 
track structure.
+  @param[in]      NewVariable             Pointer to new variable.
+  @param[in]      NewVariableSize         New variable size.
   @param[in]      ReclaimPubKeyStore      Reclaim for public key database or 
not.
-  @param[in]      ReclaimAnyway           If TRUE, do reclaim anyway.
   
   @return EFI_SUCCESS                  Reclaim operation has finished 
successfully.
-  @return EFI_OUT_OF_RESOURCES         No enough memory resources.
+  @return EFI_OUT_OF_RESOURCES         No enough memory resources or variable 
space.
   @return EFI_DEVICE_ERROR             The public key database doesn't exist.
   @return Others                       Unexpect error happened during reclaim 
operation.
 
@@ -746,8 +747,9 @@
   OUT    UINTN                        *LastVariableOffset,
   IN     BOOLEAN                      IsVolatile,
   IN OUT VARIABLE_POINTER_TRACK       *UpdatingPtrTrack,
-  IN     BOOLEAN                      ReclaimPubKeyStore,
-  IN     BOOLEAN                      ReclaimAnyway
+  IN     VARIABLE_HEADER              *NewVariable,
+  IN     UINTN                        NewVariableSize,
+  IN     BOOLEAN                      ReclaimPubKeyStore
   )
 {
   VARIABLE_HEADER       *Variable;
@@ -758,31 +760,28 @@
   UINT8                 *ValidBuffer;
   UINTN                 MaximumBufferSize;
   UINTN                 VariableSize;
-  UINTN                 VariableNameSize;
-  UINTN                 UpdatingVariableNameSize;
   UINTN                 NameSize;
   UINT8                 *CurrPtr;
   VOID                  *Point0;
   VOID                  *Point1;
   BOOLEAN               FoundAdded;
   EFI_STATUS            Status;
-  CHAR16                *VariableNamePtr;
-  CHAR16                *UpdatingVariableNamePtr;
   UINTN                 CommonVariableTotalSize;
   UINTN                 HwErrVariableTotalSize;
   UINT32                *NewPubKeyIndex;
   UINT8                 *NewPubKeyStore;
   UINT32                NewPubKeySize;
   VARIABLE_HEADER       *PubKeyHeader;
-  BOOLEAN               NeedDoReclaim;
   VARIABLE_HEADER       *UpdatingVariable;
+  VARIABLE_HEADER       *UpdatingInDeletedTransition;
 
   UpdatingVariable = NULL;
+  UpdatingInDeletedTransition = NULL;
   if (UpdatingPtrTrack != NULL) {
     UpdatingVariable = UpdatingPtrTrack->CurrPtr;
+    UpdatingInDeletedTransition = UpdatingPtrTrack->InDeletedTransitionPtr;
   }
 
-  NeedDoReclaim = FALSE;
   VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
 
   CommonVariableTotalSize = 0;
@@ -800,21 +799,22 @@
 
   while (IsValidVariableHeader (Variable)) {
     NextVariable = GetNextVariablePtr (Variable);
-    if (Variable->State == VAR_ADDED ||
-        Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
+    if ((Variable->State == VAR_ADDED || Variable->State == 
(VAR_IN_DELETED_TRANSITION & VAR_ADDED)) &&
+        Variable != UpdatingVariable &&
+        Variable != UpdatingInDeletedTransition
        ) {
       VariableSize = (UINTN) NextVariable - (UINTN) Variable;
       MaximumBufferSize += VariableSize;
-    } else {
-      NeedDoReclaim = TRUE;
     }
 
     Variable = NextVariable;
   }
 
-  if (!ReclaimAnyway && !NeedDoReclaim) {
-    DEBUG ((EFI_D_INFO, "Variable driver: no DELETED variable found, so no 
variable space could be reclaimed.\n"));
-    return EFI_SUCCESS;
+  if (NewVariable != NULL) {
+    //
+    // Add the new variable size.
+    //
+    MaximumBufferSize += NewVariableSize;
   }
 
   //
@@ -836,6 +836,7 @@
   CurrPtr = (UINT8 *) GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer);
 
   if (ReclaimPubKeyStore) {
+    ASSERT (IsVolatile == FALSE);
     //
     // Trim the PubKeyStore and get new PubKeyIndex.
     //
@@ -872,9 +873,9 @@
         CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
         ((VARIABLE_HEADER*) CurrPtr)->PubKeyIndex = 
NewPubKeyIndex[Variable->PubKeyIndex];
         CurrPtr += VariableSize;
-        if ((!IsVolatile) && ((Variable->Attributes & 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+        if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
           HwErrVariableTotalSize += VariableSize;
-        } else if ((!IsVolatile) && ((Variable->Attributes & 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+        } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) 
!= EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
           CommonVariableTotalSize += VariableSize;
         }
       }
@@ -905,25 +906,7 @@
     Variable = GetStartPointer (VariableStoreHeader);
     while (IsValidVariableHeader (Variable)) {
       NextVariable = GetNextVariablePtr (Variable);
-      if (Variable->State == VAR_ADDED) {
-        if (UpdatingVariable != NULL) {
-          if (UpdatingVariable == Variable) {
-            Variable = NextVariable;
-            continue;
-          }
-
-          VariableNameSize         = NameSizeOfVariable(Variable);
-          UpdatingVariableNameSize = NameSizeOfVariable(UpdatingVariable);
-
-          VariableNamePtr         = GetVariableNamePtr (Variable);
-          UpdatingVariableNamePtr = GetVariableNamePtr (UpdatingVariable);
-          if (CompareGuid (&Variable->VendorGuid, 
&UpdatingVariable->VendorGuid)    &&
-              VariableNameSize == UpdatingVariableNameSize &&
-              CompareMem (VariableNamePtr, UpdatingVariableNamePtr, 
VariableNameSize) == 0 ) {
-            Variable = NextVariable;
-            continue;
-          }
-        }
+      if (Variable != UpdatingVariable && Variable->State == VAR_ADDED) {
         VariableSize = (UINTN) NextVariable - (UINTN) Variable;
         CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
         CurrPtr += VariableSize;
@@ -937,28 +920,12 @@
     }
 
     //
-    // Reinstall the variable being updated if it is not NULL.
-    //
-    if (UpdatingVariable != NULL) {
-      VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - 
(UINTN)UpdatingVariable;
-      CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize);
-      UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER 
*)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer 
((VARIABLE_STORE_HEADER *) ValidBuffer)));
-      UpdatingPtrTrack->InDeletedTransitionPtr = NULL;
-      CurrPtr += VariableSize;
-      if ((!IsVolatile) && ((UpdatingVariable->Attributes & 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
-          HwErrVariableTotalSize += VariableSize;
-      } else if ((!IsVolatile) && ((UpdatingVariable->Attributes & 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
-          CommonVariableTotalSize += VariableSize;
-      }
-    }
-
-    //
     // Reinstall all in delete transition variables.
     //
-    Variable      = GetStartPointer (VariableStoreHeader);
+    Variable = GetStartPointer (VariableStoreHeader);
     while (IsValidVariableHeader (Variable)) {
       NextVariable = GetNextVariablePtr (Variable);
-      if (Variable != UpdatingVariable && Variable->State == 
(VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+      if (Variable != UpdatingVariable && Variable != 
UpdatingInDeletedTransition && Variable->State == (VAR_IN_DELETED_TRANSITION & 
VAR_ADDED)) {
 
         //
         // Buffer has cached all ADDED variable.
@@ -1001,6 +968,42 @@
 
       Variable = NextVariable;
     }
+
+    //
+    // Install the new variable if it is not NULL.
+    //
+    if (NewVariable != NULL) {
+      if ((UINTN) (CurrPtr - ValidBuffer) + NewVariableSize > 
VariableStoreHeader->Size) {
+        //
+        // No enough space to store the new variable.
+        //
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Done;
+      }
+      if (!IsVolatile) {
+        if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+          HwErrVariableTotalSize += NewVariableSize;
+        } else if ((NewVariable->Attributes & 
EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+          CommonVariableTotalSize += NewVariableSize;
+        }
+        if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) ||
+            (CommonVariableTotalSize > VariableStoreHeader->Size - sizeof 
(VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize))) {
+          //
+          // No enough space to store the new variable by NV or NV+HR 
attribute.
+          //
+          Status = EFI_OUT_OF_RESOURCES;
+          goto Done;
+        }
+      }
+
+      CopyMem (CurrPtr, (UINT8 *) NewVariable, NewVariableSize);
+      ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED;
+      if (UpdatingVariable != NULL) {
+        UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER 
*)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer 
((VARIABLE_STORE_HEADER *) ValidBuffer)));
+        UpdatingPtrTrack->InDeletedTransitionPtr = NULL;
+      }
+      CurrPtr += NewVariableSize;
+    }
   }
 
   if (IsVolatile) {
@@ -1008,7 +1011,7 @@
     // If volatile variable store, just copy valid buffer.
     //
     SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
-    CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - 
(UINT8 *) ValidBuffer));
+    CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - 
ValidBuffer));
     Status  = EFI_SUCCESS;
   } else {
     //
@@ -1017,12 +1020,12 @@
     Status = FtwVariableSpace (
               VariableBase,
               ValidBuffer,
-              (UINTN) (CurrPtr - (UINT8 *) ValidBuffer)
+              (UINTN) (CurrPtr - ValidBuffer)
               );
     CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, 
VariableStoreHeader->Size);
   }
   if (!EFI_ERROR (Status)) {
-    *LastVariableOffset = (UINTN) (CurrPtr - (UINT8 *) ValidBuffer);
+    *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
     if (!IsVolatile) {
       mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize;
       mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize;
@@ -1049,7 +1052,8 @@
   if (NewPubKeyIndex != NULL) {
     FreePool (NewPubKeyIndex);
   }
-  
+
+Done:
   FreePool (ValidBuffer);
 
   return Status;
@@ -2101,33 +2105,29 @@
         goto Done;
       }
       //
-      // Perform garbage collection & reclaim operation.
+      // Perform garbage collection & reclaim operation, and integrate the new 
variable at the same time.
       //
       Status = Reclaim (
                  mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
                  &mVariableModuleGlobal->NonVolatileLastVariableOffset,
                  FALSE,
                  Variable,
-                 FALSE,
+                 NextVariable,
+                 HEADER_ALIGN (VarSize),
                  FALSE
                  );
-      if (EFI_ERROR (Status)) {
-        goto Done;
+      if (!EFI_ERROR (Status)) {
+        //
+        // The new variable has been integrated successfully during reclaiming.
+        //
+        if (Variable->CurrPtr != NULL) {
+          CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) 
CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) 
Variable->StartPtr));
+          CacheVariable->InDeletedTransitionPtr = NULL;
+        }
+        UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, 
FALSE, FALSE);
+        FlushHobVariableToFlash (VariableName, VendorGuid);
       }
-      //
-      // If still no enough space, return out of resources.
-      //
-      if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0)
-        && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > 
PcdGet32 (PcdHwErrStorageSize)))
-        || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0)
-        && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > 
NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 
(PcdHwErrStorageSize)))) {
-        Status = EFI_OUT_OF_RESOURCES;
-        goto Done;
-      }
-      if (Variable->CurrPtr != NULL) {
-        CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) 
CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) 
Variable->StartPtr));
-        CacheVariable->InDeletedTransitionPtr = NULL;
-      }
+      goto Done;
     }
     //
     // Four steps
@@ -2225,32 +2225,28 @@
     if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) 
>
         ((VARIABLE_STORE_HEADER *) ((UINTN) 
(mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size) {
       //
-      // Perform garbage collection & reclaim operation.
+      // Perform garbage collection & reclaim operation, and integrate the new 
variable at the same time.
       //
       Status = Reclaim (
                  mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,
                  &mVariableModuleGlobal->VolatileLastVariableOffset,
                  TRUE,
                  Variable,
-                 FALSE,
+                 NextVariable,
+                 HEADER_ALIGN (VarSize),
                  FALSE
                  );
-      if (EFI_ERROR (Status)) {
-        goto Done;
+      if (!EFI_ERROR (Status)) {
+        //
+        // The new variable has been integrated successfully during reclaiming.
+        //
+        if (Variable->CurrPtr != NULL) {
+          CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) 
CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) 
Variable->StartPtr));
+          CacheVariable->InDeletedTransitionPtr = NULL;
+        }
+        UpdateVariableInfo (VariableName, VendorGuid, TRUE, FALSE, TRUE, 
FALSE, FALSE);
       }
-      //
-      // If still no enough space, return out of resources.
-      //
-      if ((UINT32) (VarSize + 
mVariableModuleGlobal->VolatileLastVariableOffset) >
-            ((VARIABLE_STORE_HEADER *) ((UINTN) 
(mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size
-            ) {
-        Status = EFI_OUT_OF_RESOURCES;
-        goto Done;
-      }
-      if (Variable->CurrPtr != NULL) {
-        CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) 
CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) 
Variable->StartPtr));
-        CacheVariable->InDeletedTransitionPtr = NULL;
-      }
+      goto Done;
     }
 
     NextVariable->State = VAR_ADDED;
@@ -3207,7 +3203,8 @@
             &mVariableModuleGlobal->NonVolatileLastVariableOffset,
             FALSE,
             NULL,
-            FALSE,
+            NULL,
+            0,
             FALSE
             );
     ASSERT_EFI_ERROR (Status);
@@ -3478,8 +3475,9 @@
                  &mVariableModuleGlobal->NonVolatileLastVariableOffset,
                  FALSE,
                  NULL,
-                 FALSE,
-                 TRUE
+                 NULL,
+                 0,
+                 FALSE
                  );
       if (EFI_ERROR (Status)) {
         return Status;

Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h  
2013-11-01 17:01:23 UTC (rev 14821)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h  
2013-11-04 03:13:54 UTC (rev 14822)
@@ -402,11 +402,12 @@
   @param[in]      IsVolatile              The variable store is volatile or 
not;
                                           if it is non-volatile, need FTW.
   @param[in, out] UpdatingPtrTrack        Pointer to updating variable pointer 
track structure.
+  @param[in]      NewVariable             Pointer to new variable.
+  @param[in]      NewVariableSize         New variable size.
   @param[in]      ReclaimPubKeyStore      Reclaim for public key database or 
not.
-  @param[in]      ReclaimAnyway           If TRUE, do reclaim anyway.
   
   @return EFI_SUCCESS                  Reclaim operation has finished 
successfully.
-  @return EFI_OUT_OF_RESOURCES         No enough memory resources.
+  @return EFI_OUT_OF_RESOURCES         No enough memory resources or variable 
space.
   @return EFI_DEVICE_ERROR             The public key database doesn't exist.
   @return Others                       Unexpect error happened during reclaim 
operation.
 
@@ -417,8 +418,9 @@
   OUT    UINTN                        *LastVariableOffset,
   IN     BOOLEAN                      IsVolatile,
   IN OUT VARIABLE_POINTER_TRACK       *UpdatingPtrTrack,
-  IN     BOOLEAN                      ReclaimPubKeyStore,
-  IN     BOOLEAN                      ReclaimAnyway
+  IN     VARIABLE_HEADER              *NewVariable,
+  IN     UINTN                        NewVariableSize,
+  IN     BOOLEAN                      ReclaimPubKeyStore
   );
 
 /**

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


------------------------------------------------------------------------------
Android is increasing in popularity, but the open development platform that
developers love is also attractive to malware creators. Download this white
paper to learn more about secure code signing practices that can help keep
Android apps secure.
http://pubads.g.doubleclick.net/gampad/clk?id=65839951&iu=/4140/ostg.clktrk
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to