]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
MdeModulePkg Variable: Handle variable Attributes mismatch case
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / Variable.c
index 834d2ff7c6db4ee060aaec22ef3956ac7d8241de..8aee8ff6a09dccb07e085d7ae809f2292d3b336a 100644 (file)
@@ -2178,6 +2178,34 @@ UpdateVariable (
     }\r
   }\r
 \r
+  //\r
+  // Check if CacheVariable points to the variable in variable HOB.\r
+  // If yes, let CacheVariable points to the variable in NV variable cache.\r
+  //\r
+  if ((CacheVariable->CurrPtr != NULL) &&\r
+      (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) &&\r
+      (CacheVariable->StartPtr == GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase))\r
+     ) {\r
+    CacheVariable->StartPtr = GetStartPointer (mNvVariableCache);\r
+    CacheVariable->EndPtr   = GetEndPointer   (mNvVariableCache);\r
+    CacheVariable->Volatile = FALSE;\r
+    Status = FindVariableEx (VariableName, VendorGuid, FALSE, CacheVariable);\r
+    if (CacheVariable->CurrPtr == NULL || EFI_ERROR (Status)) {\r
+      //\r
+      // There is no matched variable in NV variable cache.\r
+      //\r
+      if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {\r
+        //\r
+        // It is to delete variable,\r
+        // go to delete this variable in variable HOB and\r
+        // try to flush other variables from HOB to flash.\r
+        //\r
+        FlushHobVariableToFlash (VariableName, VendorGuid);\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+  }\r
+\r
   if ((CacheVariable->CurrPtr == NULL) || CacheVariable->Volatile) {\r
     Variable = CacheVariable;\r
   } else {\r
@@ -3895,6 +3923,7 @@ FlushHobVariableToFlash (
   VARIABLE_STORE_HEADER         *VariableStoreHeader;\r
   VARIABLE_HEADER               *Variable;\r
   VOID                          *VariableData;\r
+  VARIABLE_POINTER_TRACK        VariablePtrTrack;\r
   BOOLEAN                       ErrorFlag;\r
 \r
   ErrorFlag = FALSE;\r
@@ -3923,17 +3952,22 @@ FlushHobVariableToFlash (
           !CompareGuid (VendorGuid, GetVendorGuidPtr (Variable)) ||\r
           StrCmp (VariableName, GetVariableNamePtr (Variable)) != 0) {\r
         VariableData = GetVariableDataPtr (Variable);\r
-        Status = VariableServiceSetVariable (\r
+        FindVariable (GetVariableNamePtr (Variable), GetVendorGuidPtr (Variable), &VariablePtrTrack, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+        Status = UpdateVariable (\r
                    GetVariableNamePtr (Variable),\r
                    GetVendorGuidPtr (Variable),\r
-                   Variable->Attributes,\r
+                   VariableData,\r
                    DataSizeOfVariable (Variable),\r
-                   VariableData\r
-                   );\r
+                   Variable->Attributes,\r
+                   0,\r
+                   0,\r
+                   &VariablePtrTrack,\r
+                   NULL\r
+                 );\r
         DEBUG ((EFI_D_INFO, "Variable driver flush the HOB variable to flash: %g %s %r\n", GetVendorGuidPtr (Variable), GetVariableNamePtr (Variable), Status));\r
       } else {\r
         //\r
-        // The updated or deleted variable is matched with the HOB variable.\r
+        // The updated or deleted variable is matched with this HOB variable.\r
         // Don't break here because we will try to set other HOB variables\r
         // since this variable could be set successfully.\r
         //\r
@@ -3988,6 +4022,8 @@ VariableWriteServiceInitialize (
   EFI_PHYSICAL_ADDRESS            NvStorageBase;\r
   VARIABLE_ENTRY_PROPERTY         *VariableEntry;\r
 \r
+  AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
   NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);\r
   if (NvStorageBase == 0) {\r
     NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
@@ -4018,6 +4054,7 @@ VariableWriteServiceInitialize (
                  0\r
                  );\r
       if (EFI_ERROR (Status)) {\r
+        ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
         return Status;\r
       }\r
       break;\r
@@ -4065,6 +4102,7 @@ VariableWriteServiceInitialize (
     }\r
   }\r
 \r
+  ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
   return Status;\r
 }\r
 \r