]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1. Update the logic of UpdateVariable() for updating variable from:
authorlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 18 Jan 2013 01:12:32 +0000 (01:12 +0000)
committerlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 18 Jan 2013 01:12:32 +0000 (01:12 +0000)
set old variable to IN_DELETED_TRANSITION -> check if reclaim is needed(If yes, do reclaim) -> add new variable -> set old variable to DELETED if no reclaim happened.
to:
set old variable to IN_DELETED_TRANSITION -> check if reclaim is needed(If yes, do reclaim) -> add new variable -> set old variable to DELETED.
2. Update UpdateVariable() to correctly handle the case "both ADDED and IN_DELETED_TRANSITION variable are present", and delete both old ADDED and IN_DELETED_TRANSITION variable when deleting or updating variable.
3. Update VariableServiceGetNextVariableName() to return the valid IN_DELETED_TRANSITION variable if only IN_DELETED_TRANSITION variable is present.

Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14065 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h

index fad1cb323ecf9afab6f67af26077deb92568bfbc..2c980b349f4afd87a0c421a6262f251765bfee95 100644 (file)
@@ -3,7 +3,7 @@
   The common variable operation routines shared by DXE_RUNTIME variable \r
   module and DXE_SMM variable module.\r
   \r
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -504,7 +504,7 @@ GetEndPointer (
   @param LastVariableOffset      Offset of last variable.\r
   @param IsVolatile              The variable store is volatile or not;\r
                                  if it is non-volatile, need FTW.\r
-  @param UpdatingVariable        Pointer to updating variable.\r
+  @param UpdatingPtrTrack        Pointer to updating variable pointer track structure.\r
   @param ReclaimAnyway           If TRUE, do reclaim anyway.\r
 \r
   @return EFI_OUT_OF_RESOURCES\r
@@ -517,7 +517,7 @@ Reclaim (
   IN  EFI_PHYSICAL_ADDRESS  VariableBase,\r
   OUT UINTN                 *LastVariableOffset,\r
   IN  BOOLEAN               IsVolatile,\r
-  IN  VARIABLE_HEADER       *UpdatingVariable,\r
+  IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack,\r
   IN  BOOLEAN               ReclaimAnyway\r
   )\r
 {\r
@@ -542,6 +542,12 @@ Reclaim (
   UINTN                 CommonVariableTotalSize;\r
   UINTN                 HwErrVariableTotalSize;\r
   BOOLEAN               NeedDoReclaim;\r
+  VARIABLE_HEADER       *UpdatingVariable;\r
+\r
+  UpdatingVariable = NULL;\r
+  if (UpdatingPtrTrack != NULL) {\r
+    UpdatingVariable = UpdatingPtrTrack->CurrPtr;\r
+  }\r
 \r
   NeedDoReclaim = FALSE;\r
   VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);\r
@@ -635,6 +641,8 @@ Reclaim (
   if (UpdatingVariable != NULL) {\r
     VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - (UINTN)UpdatingVariable;\r
     CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize);\r
+    UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER *)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer)));\r
+    UpdatingPtrTrack->InDeletedTransitionPtr = NULL;\r
     CurrPtr += VariableSize;\r
     if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
         HwErrVariableTotalSize += VariableSize;\r
@@ -667,7 +675,7 @@ Reclaim (
            ) {\r
           Point0 = (VOID *) GetVariableNamePtr (AddedVariable);\r
           Point1 = (VOID *) GetVariableNamePtr (Variable);\r
-          if (CompareMem (Point0, Point1, NameSizeOfVariable (AddedVariable)) == 0) {\r
+          if (CompareMem (Point0, Point1, NameSize) == 0) {\r
             FoundAdded = TRUE;\r
             break;\r
           }\r
@@ -760,6 +768,8 @@ FindVariableEx (
   VARIABLE_HEADER                *InDeletedVariable;\r
   VOID                           *Point;\r
 \r
+  PtrTrack->InDeletedTransitionPtr = NULL;\r
+\r
   //\r
   // Find the variable by walk through HOB, volatile and non-volatile variable store.\r
   //\r
@@ -777,6 +787,7 @@ FindVariableEx (
           if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
             InDeletedVariable   = PtrTrack->CurrPtr;\r
           } else {\r
+            PtrTrack->InDeletedTransitionPtr = InDeletedVariable;\r
             return EFI_SUCCESS;\r
           }\r
         } else {\r
@@ -788,6 +799,7 @@ FindVariableEx (
               if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
                 InDeletedVariable     = PtrTrack->CurrPtr;\r
               } else {\r
+                PtrTrack->InDeletedTransitionPtr = InDeletedVariable;\r
                 return EFI_SUCCESS;\r
               }\r
             }\r
@@ -1320,7 +1332,7 @@ AutoUpdateLangVariable (
         //\r
         // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.\r
         //\r
-        FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, (VARIABLE_GLOBAL *)mVariableModuleGlobal, FALSE);\r
+        FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
 \r
         Status = UpdateVariable (L"Lang", &gEfiGlobalVariableGuid, BestLang,\r
                                  ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable);\r
@@ -1375,7 +1387,7 @@ AutoUpdateLangVariable (
   @param[in] Data               Variable data.\r
   @param[in] DataSize           Size of data. 0 means delete.\r
   @param[in] Attributes         Attribues of the variable.\r
-  @param[in] CacheVariable      The variable information which is used to keep track of variable usage.\r
+  @param[in, out] CacheVariable The variable information which is used to keep track of variable usage.\r
   \r
   @retval EFI_SUCCESS           The update operation is success.\r
   @retval EFI_OUT_OF_RESOURCES  Variable region is full, can not write other data into this region.\r
@@ -1388,7 +1400,7 @@ UpdateVariable (
   IN      VOID                        *Data,\r
   IN      UINTN                       DataSize,\r
   IN      UINT32                      Attributes      OPTIONAL,\r
-  IN      VARIABLE_POINTER_TRACK      *CacheVariable\r
+  IN OUT  VARIABLE_POINTER_TRACK      *CacheVariable\r
   )\r
 {\r
   EFI_STATUS                          Status;\r
@@ -1402,7 +1414,6 @@ UpdateVariable (
   BOOLEAN                             Volatile;\r
   EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;\r
   UINT8                               State;\r
-  BOOLEAN                             Reclaimed;\r
   VARIABLE_POINTER_TRACK              *Variable;\r
   VARIABLE_POINTER_TRACK              NvVariable;\r
   VARIABLE_STORE_HEADER               *VariableStoreHeader;\r
@@ -1429,11 +1440,15 @@ UpdateVariable (
     Variable->StartPtr = GetStartPointer (VariableStoreHeader);\r
     Variable->EndPtr   = GetEndPointer (VariableStoreHeader);\r
     Variable->CurrPtr  = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->CurrPtr - (UINTN)CacheVariable->StartPtr));\r
+    if (CacheVariable->InDeletedTransitionPtr != NULL) {\r
+      Variable->InDeletedTransitionPtr = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->InDeletedTransitionPtr - (UINTN)CacheVariable->StartPtr));\r
+    } else {\r
+      Variable->InDeletedTransitionPtr = NULL;\r
+    }\r
     Variable->Volatile = FALSE;\r
   } \r
 \r
   Fvb       = mVariableModuleGlobal->FvbInstance;\r
-  Reclaimed = FALSE;\r
 \r
   if (Variable->CurrPtr != NULL) {\r
     //\r
@@ -1463,6 +1478,31 @@ UpdateVariable (
     // causes it to be deleted.\r
     //\r
     if (DataSize == 0 || (Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0) {    \r
+      if (Variable->InDeletedTransitionPtr != NULL) {\r
+        //\r
+        // Both ADDED and IN_DELETED_TRANSITION variable are present,\r
+        // set IN_DELETED_TRANSITION one to DELETED state first.\r
+        //\r
+        State = Variable->InDeletedTransitionPtr->State;\r
+        State &= VAR_DELETED;\r
+        Status = UpdateVariableStore (\r
+                   &mVariableModuleGlobal->VariableGlobal,\r
+                   Variable->Volatile,\r
+                   FALSE,\r
+                   Fvb,\r
+                   (UINTN) &Variable->InDeletedTransitionPtr->State,\r
+                   sizeof (UINT8),\r
+                   &State\r
+                   );\r
+        if (!EFI_ERROR (Status)) {\r
+          if (!Variable->Volatile) {\r
+            CacheVariable->InDeletedTransitionPtr->State = State;\r
+          }\r
+        } else {\r
+          goto Done;\r
+        }\r
+      }\r
+\r
       State = Variable->CurrPtr->State;\r
       State &= VAR_DELETED;\r
 \r
@@ -1607,7 +1647,7 @@ UpdateVariable (
       // Perform garbage collection & reclaim operation.\r
       //\r
       Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, \r
-                        &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable->CurrPtr, FALSE);\r
+                        &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable, FALSE);\r
       if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
@@ -1621,7 +1661,10 @@ UpdateVariable (
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
-      Reclaimed = TRUE;\r
+      if (Variable->CurrPtr != NULL) {\r
+        CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));\r
+        CacheVariable->InDeletedTransitionPtr = NULL;\r
+      }\r
     }\r
     //\r
     // Four steps\r
@@ -1722,7 +1765,7 @@ UpdateVariable (
       // Perform garbage collection & reclaim operation.\r
       //\r
       Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, \r
-                          &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable->CurrPtr, FALSE);\r
+                          &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable, FALSE);\r
       if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
@@ -1735,7 +1778,10 @@ UpdateVariable (
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
-      Reclaimed = TRUE;\r
+      if (Variable->CurrPtr != NULL) {\r
+        CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));\r
+        CacheVariable->InDeletedTransitionPtr = NULL;\r
+      }\r
     }\r
 \r
     NextVariable->State = VAR_ADDED;\r
@@ -1759,7 +1805,32 @@ UpdateVariable (
   //\r
   // Mark the old variable as deleted.\r
   //\r
-  if (!Reclaimed && !EFI_ERROR (Status) && Variable->CurrPtr != NULL) {\r
+  if (!EFI_ERROR (Status) && Variable->CurrPtr != NULL) {\r
+    if (Variable->InDeletedTransitionPtr != NULL) {\r
+      //\r
+      // Both ADDED and IN_DELETED_TRANSITION old variable are present,\r
+      // set IN_DELETED_TRANSITION one to DELETED state first.\r
+      //\r
+      State = Variable->InDeletedTransitionPtr->State;\r
+      State &= VAR_DELETED;\r
+      Status = UpdateVariableStore (\r
+                 &mVariableModuleGlobal->VariableGlobal,\r
+                 Variable->Volatile,\r
+                 FALSE,\r
+                 Fvb,\r
+                 (UINTN) &Variable->InDeletedTransitionPtr->State,\r
+                 sizeof (UINT8),\r
+                 &State\r
+                 );\r
+      if (!EFI_ERROR (Status)) {\r
+        if (!Variable->Volatile) {\r
+          CacheVariable->InDeletedTransitionPtr->State = State;\r
+        }\r
+      } else {\r
+        goto Done;\r
+      }\r
+    }\r
+\r
     State = Variable->CurrPtr->State;\r
     State &= VAR_DELETED;\r
 \r
@@ -1947,6 +2018,7 @@ VariableServiceGetNextVariableName (
   VARIABLE_STORE_TYPE     Type;\r
   VARIABLE_POINTER_TRACK  Variable;\r
   VARIABLE_POINTER_TRACK  VariableInHob;\r
+  VARIABLE_POINTER_TRACK  VariablePtrTrack;\r
   UINTN                   VarNameSize;\r
   EFI_STATUS              Status;\r
   VARIABLE_STORE_HEADER   *VariableStoreHeader[VariableStoreTypeMax];\r
@@ -2020,8 +2092,27 @@ VariableServiceGetNextVariableName (
     //\r
     // Variable is found\r
     //\r
-    if (Variable.CurrPtr->State == VAR_ADDED) {\r
-      if ((AtRuntime () && ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) == 0) {\r
+    if (Variable.CurrPtr->State == VAR_ADDED || Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
+      if (!AtRuntime () || ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {\r
+        if (Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
+          //\r
+          // If it is a IN_DELETED_TRANSITION variable,\r
+          // and there is also a same ADDED one at the same time,\r
+          // don't return it.\r
+          //\r
+          VariablePtrTrack.StartPtr = Variable.StartPtr;\r
+          VariablePtrTrack.EndPtr = Variable.EndPtr;\r
+          Status = FindVariableEx (\r
+                     GetVariableNamePtr (Variable.CurrPtr),\r
+                     &Variable.CurrPtr->VendorGuid,\r
+                     FALSE,\r
+                     &VariablePtrTrack\r
+                     );\r
+          if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State == VAR_ADDED) {\r
+            Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
+            continue;\r
+          }\r
+        }\r
 \r
         //\r
         // Don't return NV variable when HOB overrides it\r
index cd88177dba0e308095ddb434a418b57110385054..8504ce05f7302c9701530567808413da824df7de 100644 (file)
@@ -3,7 +3,7 @@
   The internal header file includes the common header files, defines\r
   internal structure and functions used by Variable modules.\r
 \r
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -56,6 +56,13 @@ typedef enum {
 \r
 typedef struct {\r
   VARIABLE_HEADER *CurrPtr;\r
+  //\r
+  // If both ADDED and IN_DELETED_TRANSITION variable are present,\r
+  // InDeletedTransitionPtr will point to the IN_DELETED_TRANSITION one.\r
+  // Otherwise, CurrPtr will point to the ADDED or IN_DELETED_TRANSITION one,\r
+  // and InDeletedTransitionPtr will be NULL at the same time.\r
+  //\r
+  VARIABLE_HEADER *InDeletedTransitionPtr;\r
   VARIABLE_HEADER *EndPtr;\r
   VARIABLE_HEADER *StartPtr;\r
   BOOLEAN         Volatile;\r
@@ -141,7 +148,7 @@ FtwVariableSpace (
 \r
   @param[in] Attributes         Attribues of the variable.\r
 \r
-  @param[in] Variable           The variable information that is used to keep track of variable usage.\r
+  @param[in, out] Variable      The variable information that is used to keep track of variable usage.\r
 \r
   @retval EFI_SUCCESS           The update operation is success.\r
 \r
@@ -155,7 +162,7 @@ UpdateVariable (
   IN      VOID            *Data,\r
   IN      UINTN           DataSize,\r
   IN      UINT32          Attributes OPTIONAL,\r
-  IN      VARIABLE_POINTER_TRACK *Variable\r
+  IN OUT  VARIABLE_POINTER_TRACK *Variable\r
   );\r
 \r
 \r
index b192731ef44e4f2c3294b9acd90f5321ab349f9b..c70b467ff9187899cf22041c2867e99ec7309cdd 100644 (file)
@@ -655,7 +655,7 @@ PubKeyStoreFilter (
   @param[out]  LastVariableOffset      Offset of last variable.\r
   @param[in]   IsVolatile              The variable store is volatile or not;\r
                                        if it is non-volatile, need FTW.\r
-  @param[in]   UpdatingVariable        Pointer to updating variable.\r
+  @param[in, out] UpdatingPtrTrack     Pointer to updating variable pointer track structure.\r
   @param[in]   ReclaimPubKeyStore      Reclaim for public key database or not.\r
   @param[in]   ReclaimAnyway           If TRUE, do reclaim anyway.\r
   \r
@@ -669,7 +669,7 @@ Reclaim (
   IN  EFI_PHYSICAL_ADDRESS  VariableBase,\r
   OUT UINTN                 *LastVariableOffset,\r
   IN  BOOLEAN               IsVolatile,\r
-  IN  VARIABLE_HEADER       *UpdatingVariable,\r
+  IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack,\r
   IN  BOOLEAN               ReclaimPubKeyStore,\r
   IN  BOOLEAN               ReclaimAnyway\r
   )\r
@@ -699,6 +699,12 @@ Reclaim (
   UINT32                NewPubKeySize;\r
   VARIABLE_HEADER       *PubKeyHeader;\r
   BOOLEAN               NeedDoReclaim;\r
+  VARIABLE_HEADER       *UpdatingVariable;\r
+\r
+  UpdatingVariable = NULL;\r
+  if (UpdatingPtrTrack != NULL) {\r
+    UpdatingVariable = UpdatingPtrTrack->CurrPtr;\r
+  }\r
 \r
   NeedDoReclaim = FALSE;\r
   VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);\r
@@ -853,6 +859,8 @@ Reclaim (
     if (UpdatingVariable != NULL) {\r
       VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - (UINTN)UpdatingVariable;\r
       CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize);\r
+      UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER *)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer)));\r
+      UpdatingPtrTrack->InDeletedTransitionPtr = NULL;\r
       CurrPtr += VariableSize;\r
       if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
           HwErrVariableTotalSize += VariableSize;\r
@@ -885,7 +893,7 @@ Reclaim (
              ) {\r
             Point0 = (VOID *) GetVariableNamePtr (AddedVariable);\r
             Point1 = (VOID *) GetVariableNamePtr (Variable);\r
-            if (CompareMem (Point0, Point1, NameSizeOfVariable (AddedVariable)) == 0) {\r
+            if (CompareMem (Point0, Point1, NameSize) == 0) {\r
               FoundAdded = TRUE;\r
               break;\r
             }\r
@@ -987,6 +995,8 @@ FindVariableEx (
   VARIABLE_HEADER                *InDeletedVariable;\r
   VOID                           *Point;\r
 \r
+  PtrTrack->InDeletedTransitionPtr = NULL;\r
+\r
   //\r
   // Find the variable by walk through HOB, volatile and non-volatile variable store.\r
   //\r
@@ -1004,6 +1014,7 @@ FindVariableEx (
           if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
             InDeletedVariable   = PtrTrack->CurrPtr;\r
           } else {\r
+            PtrTrack->InDeletedTransitionPtr = InDeletedVariable;\r
             return EFI_SUCCESS;\r
           }\r
         } else {\r
@@ -1015,6 +1026,7 @@ FindVariableEx (
               if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
                 InDeletedVariable     = PtrTrack->CurrPtr;\r
               } else {\r
+                PtrTrack->InDeletedTransitionPtr = InDeletedVariable;\r
                 return EFI_SUCCESS;\r
               }\r
             }\r
@@ -1606,7 +1618,7 @@ AutoUpdateLangVariable (
   @param[in] Attributes         Attributes of the variable.\r
   @param[in] KeyIndex           Index of associated public key.\r
   @param[in] MonotonicCount     Value of associated monotonic count.\r
-  @param[in] CacheVariable      The variable information which is used to keep track of variable usage.\r
+  @param[in, out] CacheVariable The variable information which is used to keep track of variable usage.\r
   @param[in] TimeStamp          Value of associated TimeStamp.\r
 \r
   @retval EFI_SUCCESS           The update operation is success.\r
@@ -1622,7 +1634,7 @@ UpdateVariable (
   IN      UINT32                      Attributes      OPTIONAL,\r
   IN      UINT32                      KeyIndex        OPTIONAL,\r
   IN      UINT64                      MonotonicCount  OPTIONAL,\r
-  IN      VARIABLE_POINTER_TRACK      *CacheVariable,\r
+  IN OUT  VARIABLE_POINTER_TRACK      *CacheVariable,\r
   IN      EFI_TIME                    *TimeStamp      OPTIONAL\r
   )\r
 {\r
@@ -1638,7 +1650,6 @@ UpdateVariable (
   BOOLEAN                             Volatile;\r
   EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *Fvb;\r
   UINT8                               State;\r
-  BOOLEAN                             Reclaimed;\r
   VARIABLE_POINTER_TRACK              *Variable;\r
   VARIABLE_POINTER_TRACK              NvVariable;\r
   VARIABLE_STORE_HEADER               *VariableStoreHeader;\r
@@ -1678,11 +1689,15 @@ UpdateVariable (
     Variable->StartPtr = GetStartPointer (VariableStoreHeader);\r
     Variable->EndPtr   = GetEndPointer (VariableStoreHeader);\r
     Variable->CurrPtr  = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->CurrPtr - (UINTN)CacheVariable->StartPtr));\r
+    if (CacheVariable->InDeletedTransitionPtr != NULL) {\r
+      Variable->InDeletedTransitionPtr = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->InDeletedTransitionPtr - (UINTN)CacheVariable->StartPtr));\r
+    } else {\r
+      Variable->InDeletedTransitionPtr = NULL;\r
+    }\r
     Variable->Volatile = FALSE;\r
   }\r
 \r
   Fvb       = mVariableModuleGlobal->FvbInstance;\r
-  Reclaimed = FALSE;\r
 \r
   //\r
   // Tricky part: Use scratch data area at the end of volatile variable store\r
@@ -1730,6 +1745,31 @@ UpdateVariable (
     // not delete the variable.\r
     //\r
     if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0))|| ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0)) {\r
+      if (Variable->InDeletedTransitionPtr != NULL) {\r
+        //\r
+        // Both ADDED and IN_DELETED_TRANSITION variable are present,\r
+        // set IN_DELETED_TRANSITION one to DELETED state first.\r
+        //\r
+        State = Variable->InDeletedTransitionPtr->State;\r
+        State &= VAR_DELETED;\r
+        Status = UpdateVariableStore (\r
+                   &mVariableModuleGlobal->VariableGlobal,\r
+                   Variable->Volatile,\r
+                   FALSE,\r
+                   Fvb,\r
+                   (UINTN) &Variable->InDeletedTransitionPtr->State,\r
+                   sizeof (UINT8),\r
+                   &State\r
+                   );\r
+        if (!EFI_ERROR (Status)) {\r
+          if (!Variable->Volatile) {\r
+            CacheVariable->InDeletedTransitionPtr->State = State;\r
+          }\r
+        } else {\r
+          goto Done;\r
+        }\r
+      }\r
+\r
       State = Variable->CurrPtr->State;\r
       State &= VAR_DELETED;\r
 \r
@@ -1959,7 +1999,7 @@ UpdateVariable (
                  mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,\r
                  &mVariableModuleGlobal->NonVolatileLastVariableOffset,\r
                  FALSE,\r
-                 Variable->CurrPtr,\r
+                 Variable,\r
                  FALSE,\r
                  FALSE\r
                  );\r
@@ -1976,7 +2016,10 @@ UpdateVariable (
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
-      Reclaimed = TRUE;\r
+      if (Variable->CurrPtr != NULL) {\r
+        CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));\r
+        CacheVariable->InDeletedTransitionPtr = NULL;\r
+      }\r
     }\r
     //\r
     // Four steps\r
@@ -2080,7 +2123,7 @@ UpdateVariable (
                  mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,\r
                  &mVariableModuleGlobal->VolatileLastVariableOffset,\r
                  TRUE,\r
-                 Variable->CurrPtr,\r
+                 Variable,\r
                  FALSE,\r
                  FALSE\r
                  );\r
@@ -2096,7 +2139,10 @@ UpdateVariable (
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
-      Reclaimed = TRUE;\r
+      if (Variable->CurrPtr != NULL) {\r
+        CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));\r
+        CacheVariable->InDeletedTransitionPtr = NULL;\r
+      }\r
     }\r
 \r
     NextVariable->State = VAR_ADDED;\r
@@ -2120,7 +2166,32 @@ UpdateVariable (
   //\r
   // Mark the old variable as deleted.\r
   //\r
-  if (!Reclaimed && !EFI_ERROR (Status) && Variable->CurrPtr != NULL) {\r
+  if (!EFI_ERROR (Status) && Variable->CurrPtr != NULL) {\r
+    if (Variable->InDeletedTransitionPtr != NULL) {\r
+      //\r
+      // Both ADDED and IN_DELETED_TRANSITION old variable are present,\r
+      // set IN_DELETED_TRANSITION one to DELETED state first.\r
+      //\r
+      State = Variable->InDeletedTransitionPtr->State;\r
+      State &= VAR_DELETED;\r
+      Status = UpdateVariableStore (\r
+                 &mVariableModuleGlobal->VariableGlobal,\r
+                 Variable->Volatile,\r
+                 FALSE,\r
+                 Fvb,\r
+                 (UINTN) &Variable->InDeletedTransitionPtr->State,\r
+                 sizeof (UINT8),\r
+                 &State\r
+                 );\r
+      if (!EFI_ERROR (Status)) {\r
+        if (!Variable->Volatile) {\r
+          CacheVariable->InDeletedTransitionPtr->State = State;\r
+        }\r
+      } else {\r
+        goto Done;\r
+      }\r
+    }\r
+\r
     State = Variable->CurrPtr->State;\r
     State &= VAR_DELETED;\r
 \r
@@ -2342,6 +2413,7 @@ VariableServiceGetNextVariableName (
   VARIABLE_STORE_TYPE     Type;\r
   VARIABLE_POINTER_TRACK  Variable;\r
   VARIABLE_POINTER_TRACK  VariableInHob;\r
+  VARIABLE_POINTER_TRACK  VariablePtrTrack;\r
   UINTN                   VarNameSize;\r
   EFI_STATUS              Status;\r
   VARIABLE_STORE_HEADER   *VariableStoreHeader[VariableStoreTypeMax];\r
@@ -2415,8 +2487,27 @@ VariableServiceGetNextVariableName (
     //\r
     // Variable is found\r
     //\r
-    if (Variable.CurrPtr->State == VAR_ADDED) {\r
-      if ((AtRuntime () && ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) == 0) {\r
+    if (Variable.CurrPtr->State == VAR_ADDED || Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
+      if (!AtRuntime () || ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {\r
+        if (Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
+          //\r
+          // If it is a IN_DELETED_TRANSITION variable,\r
+          // and there is also a same ADDED one at the same time,\r
+          // don't return it.\r
+          //\r
+          VariablePtrTrack.StartPtr = Variable.StartPtr;\r
+          VariablePtrTrack.EndPtr = Variable.EndPtr;\r
+          Status = FindVariableEx (\r
+                     GetVariableNamePtr (Variable.CurrPtr),\r
+                     &Variable.CurrPtr->VendorGuid,\r
+                     FALSE,\r
+                     &VariablePtrTrack\r
+                     );\r
+          if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State == VAR_ADDED) {\r
+            Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
+            continue;\r
+          }\r
+        }\r
 \r
         //\r
         // Don't return NV variable when HOB overrides it\r
index 427245abcecfdb291cfd8ecc9574c04eebef7266..8e292f36b21968ef24aad63ad255c281d6502e78 100644 (file)
@@ -65,6 +65,13 @@ typedef enum {
 \r
 typedef struct {\r
   VARIABLE_HEADER *CurrPtr;\r
+  //\r
+  // If both ADDED and IN_DELETED_TRANSITION variable are present,\r
+  // InDeletedTransitionPtr will point to the IN_DELETED_TRANSITION one.\r
+  // Otherwise, CurrPtr will point to the ADDED or IN_DELETED_TRANSITION one,\r
+  // and InDeletedTransitionPtr will be NULL at the same time.\r
+  //\r
+  VARIABLE_HEADER *InDeletedTransitionPtr;\r
   VARIABLE_HEADER *EndPtr;\r
   VARIABLE_HEADER *StartPtr;\r
   BOOLEAN         Volatile;\r
@@ -209,7 +216,7 @@ DataSizeOfVariable (
   @param[in] Attributes         Attributes of the variable.\r
   @param[in] KeyIndex           Index of associated public key.\r
   @param[in] MonotonicCount     Value of associated monotonic count.\r
-  @param[in] Variable           The variable information that is used to keep track of variable usage.\r
+  @param[in, out] Variable      The variable information that is used to keep track of variable usage.\r
 \r
   @param[in] TimeStamp          Value of associated TimeStamp.\r
 \r
@@ -226,7 +233,7 @@ UpdateVariable (
   IN      UINT32          Attributes OPTIONAL,\r
   IN      UINT32          KeyIndex  OPTIONAL,\r
   IN      UINT64          MonotonicCount  OPTIONAL,\r
-  IN      VARIABLE_POINTER_TRACK *Variable,\r
+  IN OUT  VARIABLE_POINTER_TRACK *Variable,\r
   IN      EFI_TIME        *TimeStamp  OPTIONAL  \r
   );\r
 \r
@@ -378,7 +385,7 @@ VariableCommonInitialize (
   @param[out]  LastVariableOffset      Offset of last variable.\r
   @param[in]   IsVolatile              The variable store is volatile or not;\r
                                        if it is non-volatile, need FTW.\r
-  @param[in]   UpdatingVariable        Pointer to updating variable.\r
+  @param[in, out] UpdatingPtrTrack     Pointer to updating variable pointer track structure.\r
   @param[in]   ReclaimPubKeyStore      Reclaim for public key database or not.\r
   @param[in]   ReclaimAnyway           If TRUE, do reclaim anyway.\r
   \r
@@ -392,7 +399,7 @@ Reclaim (
   IN  EFI_PHYSICAL_ADDRESS  VariableBase,\r
   OUT UINTN                 *LastVariableOffset,\r
   IN  BOOLEAN               IsVolatile,\r
-  IN  VARIABLE_HEADER       *UpdatingVariable,\r
+  IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack,\r
   IN  BOOLEAN               ReclaimPubKeyStore,\r
   IN  BOOLEAN               ReclaimAnyway\r
   );\r