]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
MdeModulePkg/Variable/RuntimeDxe: introduce PcdMaxVolatileVariableSize
[mirror_edk2.git] / MdeModulePkg / Universal / Variable / RuntimeDxe / Variable.c
index 793bdad3b92ee057668799978841691404d0699b..6caf603b3d305f41b43c45c966a6957a014bff31 100644 (file)
@@ -2345,12 +2345,14 @@ UpdateVariable (
         CopyMem (BufferForMerge, (UINT8 *) ((UINTN) CacheVariable->CurrPtr + DataOffset), DataSizeOfVariable (CacheVariable->CurrPtr));\r
 \r
         //\r
-        // Set Max Common/Auth Variable Data Size as default MaxDataSize.\r
+        // Set Max Auth/Non-Volatile/Volatile Variable Data Size as default MaxDataSize.\r
         //\r
         if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) {\r
           MaxDataSize = mVariableModuleGlobal->MaxAuthVariableSize - DataOffset;\r
-        } else {\r
+        } else if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
           MaxDataSize = mVariableModuleGlobal->MaxVariableSize - DataOffset;\r
+        } else {\r
+          MaxDataSize = mVariableModuleGlobal->MaxVolatileVariableSize - DataOffset;\r
         }\r
 \r
         //\r
@@ -3218,16 +3220,20 @@ VariableServiceSetVariable (
   } else {\r
     //\r
     //  The size of the VariableName, including the Unicode Null in bytes plus\r
-    //  the DataSize is limited to maximum size of Max(Auth)VariableSize bytes.\r
+    //  the DataSize is limited to maximum size of Max(Auth|Volatile)VariableSize bytes.\r
     //\r
     if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) {\r
       if (StrSize (VariableName) + PayloadSize > mVariableModuleGlobal->MaxAuthVariableSize - GetVariableHeaderSize ()) {\r
         return EFI_INVALID_PARAMETER;\r
       }\r
-    } else {\r
+    } else if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
       if (StrSize (VariableName) + PayloadSize > mVariableModuleGlobal->MaxVariableSize - GetVariableHeaderSize ()) {\r
         return EFI_INVALID_PARAMETER;\r
       }\r
+    } else {\r
+      if (StrSize (VariableName) + PayloadSize > mVariableModuleGlobal->MaxVolatileVariableSize - GetVariableHeaderSize ()) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
     }\r
   }\r
 \r
@@ -3399,12 +3405,14 @@ VariableServiceQueryVariableInfoInternal (
     }\r
 \r
     //\r
-    // Let *MaximumVariableSize be Max(Auth)VariableSize with the exception of the variable header size.\r
+    // Let *MaximumVariableSize be Max(Auth|Volatile)VariableSize with the exception of the variable header size.\r
     //\r
     if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) {\r
       *MaximumVariableSize = mVariableModuleGlobal->MaxAuthVariableSize - GetVariableHeaderSize ();\r
-    } else {\r
+    } else if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
       *MaximumVariableSize = mVariableModuleGlobal->MaxVariableSize - GetVariableHeaderSize ();\r
+    } else {\r
+      *MaximumVariableSize = mVariableModuleGlobal->MaxVolatileVariableSize - GetVariableHeaderSize ();\r
     }\r
   }\r
 \r
@@ -3657,6 +3665,30 @@ GetNonVolatileMaxVariableSize (
   }\r
 }\r
 \r
+/**\r
+  Get maximum variable size, covering both non-volatile and volatile variables.\r
+\r
+  @return Maximum variable size.\r
+\r
+**/\r
+UINTN\r
+GetMaxVariableSize (\r
+  VOID\r
+  )\r
+{\r
+  UINTN MaxVariableSize;\r
+\r
+  MaxVariableSize = GetNonVolatileMaxVariableSize();\r
+  //\r
+  // The condition below fails implicitly if PcdMaxVolatileVariableSize equals\r
+  // the default zero value.\r
+  //\r
+  if (MaxVariableSize < PcdGet32 (PcdMaxVolatileVariableSize)) {\r
+    MaxVariableSize = PcdGet32 (PcdMaxVolatileVariableSize);\r
+  }\r
+  return MaxVariableSize;\r
+}\r
+\r
 /**\r
   Init non-volatile variable store.\r
 \r
@@ -4036,7 +4068,105 @@ VariableWriteServiceInitialize (
   return Status;\r
 }\r
 \r
+/**\r
+  Convert normal variable storage to the allocated auth variable storage.\r
+\r
+  @param[in]  NormalVarStorage  Pointer to the normal variable storage header\r
+\r
+  @retval the allocated auth variable storage\r
+**/\r
+VOID *\r
+ConvertNormalVarStorageToAuthVarStorage (\r
+  VARIABLE_STORE_HEADER *NormalVarStorage\r
+  )\r
+{\r
+  VARIABLE_HEADER *StartPtr;\r
+  UINT8           *NextPtr;\r
+  VARIABLE_HEADER *EndPtr;\r
+  UINTN           AuthVarStroageSize;\r
+  AUTHENTICATED_VARIABLE_HEADER *AuthStartPtr;\r
+  VARIABLE_STORE_HEADER         *AuthVarStorage;\r
+\r
+  AuthVarStroageSize  = sizeof (VARIABLE_STORE_HEADER);\r
+  //\r
+  // Set AuthFormat as FALSE for normal variable storage\r
+  //\r
+  mVariableModuleGlobal->VariableGlobal.AuthFormat = FALSE;\r
+\r
+  //\r
+  // Calculate Auth Variable Storage Size\r
+  //\r
+  StartPtr = GetStartPointer (NormalVarStorage);\r
+  EndPtr   = GetEndPointer (NormalVarStorage);\r
+  while (StartPtr < EndPtr) {\r
+    if (StartPtr->State == VAR_ADDED) {\r
+      AuthVarStroageSize = HEADER_ALIGN (AuthVarStroageSize);\r
+      AuthVarStroageSize += sizeof (AUTHENTICATED_VARIABLE_HEADER);\r
+      AuthVarStroageSize += StartPtr->NameSize + GET_PAD_SIZE (StartPtr->NameSize);\r
+      AuthVarStroageSize += StartPtr->DataSize + GET_PAD_SIZE (StartPtr->DataSize);\r
+    }\r
+    StartPtr  = GetNextVariablePtr (StartPtr);\r
+  }\r
+\r
+  //\r
+  // Allocate Runtime memory for Auth Variable Storage\r
+  //\r
+  AuthVarStorage = AllocateRuntimeZeroPool (AuthVarStroageSize);\r
+  ASSERT (AuthVarStorage != NULL);\r
+  if (AuthVarStorage == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Copy Variable from Normal storage to Auth storage\r
+  //\r
+  StartPtr = GetStartPointer (NormalVarStorage);\r
+  EndPtr   = GetEndPointer (NormalVarStorage);\r
+  AuthStartPtr = (AUTHENTICATED_VARIABLE_HEADER *) GetStartPointer (AuthVarStorage);\r
+  while (StartPtr < EndPtr) {\r
+    if (StartPtr->State == VAR_ADDED) {\r
+      AuthStartPtr = (AUTHENTICATED_VARIABLE_HEADER *) HEADER_ALIGN (AuthStartPtr);\r
+      //\r
+      // Copy Variable Header\r
+      //\r
+      AuthStartPtr->StartId     = StartPtr->StartId;\r
+      AuthStartPtr->State       = StartPtr->State;\r
+      AuthStartPtr->Attributes  = StartPtr->Attributes;\r
+      AuthStartPtr->NameSize    = StartPtr->NameSize;\r
+      AuthStartPtr->DataSize    = StartPtr->DataSize;\r
+      CopyGuid (&AuthStartPtr->VendorGuid, &StartPtr->VendorGuid);\r
+      //\r
+      // Copy Variable Name\r
+      //\r
+      NextPtr = (UINT8 *) (AuthStartPtr + 1);\r
+      CopyMem (NextPtr, GetVariableNamePtr (StartPtr), AuthStartPtr->NameSize);\r
+      //\r
+      // Copy Variable Data\r
+      //\r
+      NextPtr = NextPtr + AuthStartPtr->NameSize + GET_PAD_SIZE (AuthStartPtr->NameSize);\r
+      CopyMem (NextPtr, GetVariableDataPtr (StartPtr), AuthStartPtr->DataSize);\r
+      //\r
+      // Go to next variable\r
+      //\r
+      AuthStartPtr = (AUTHENTICATED_VARIABLE_HEADER *) (NextPtr + AuthStartPtr->DataSize + GET_PAD_SIZE (AuthStartPtr->DataSize));\r
+    }\r
+    StartPtr = GetNextVariablePtr (StartPtr);\r
+  }\r
+  //\r
+  // Update Auth Storage Header\r
+  //\r
+  AuthVarStorage->Format = NormalVarStorage->Format;\r
+  AuthVarStorage->State  = NormalVarStorage->State;\r
+  AuthVarStorage->Size = (UINT32)((UINTN)AuthStartPtr - (UINTN)AuthVarStorage);\r
+  CopyGuid (&AuthVarStorage->Signature, &gEfiAuthenticatedVariableGuid);\r
+  ASSERT (AuthVarStorage->Size <= AuthVarStroageSize);\r
 \r
+  //\r
+  // Restore AuthFormat\r
+  //\r
+  mVariableModuleGlobal->VariableGlobal.AuthFormat = TRUE;\r
+  return AuthVarStorage;\r
+}\r
 /**\r
   Initializes variable store area for non-volatile and volatile variable.\r
 \r
@@ -4057,6 +4187,7 @@ VariableCommonInitialize (
   EFI_HOB_GUID_TYPE               *GuidHob;\r
   EFI_GUID                        *VariableGuid;\r
   EFI_FIRMWARE_VOLUME_HEADER      *NvFvHeader;\r
+  BOOLEAN                         IsNormalVariableHob;\r
 \r
   //\r
   // Allocate runtime memory for variable driver global structure.\r
@@ -4098,12 +4229,24 @@ VariableCommonInitialize (
   //\r
   // Get HOB variable store.\r
   //\r
+  IsNormalVariableHob = FALSE;\r
   GuidHob = GetFirstGuidHob (VariableGuid);\r
+  if (GuidHob == NULL && VariableGuid == &gEfiAuthenticatedVariableGuid) {\r
+    //\r
+    // Try getting it from normal variable HOB\r
+    //\r
+    GuidHob = GetFirstGuidHob (&gEfiVariableGuid);\r
+    IsNormalVariableHob = TRUE;\r
+  }\r
   if (GuidHob != NULL) {\r
     VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob);\r
     VariableStoreLength = GuidHob->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE);\r
     if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {\r
-      mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateRuntimeCopyPool ((UINTN) VariableStoreLength, (VOID *) VariableStoreHeader);\r
+      if (!IsNormalVariableHob) {\r
+        mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateRuntimeCopyPool ((UINTN) VariableStoreLength, (VOID *) VariableStoreHeader);\r
+      } else {\r
+        mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) ConvertNormalVarStorageToAuthVarStorage ((VOID *) VariableStoreHeader);\r
+      }\r
       if (mVariableModuleGlobal->VariableGlobal.HobVariableBase == 0) {\r
         FreePool (NvFvHeader);\r
         FreePool (mVariableModuleGlobal);\r
@@ -4114,10 +4257,14 @@ VariableCommonInitialize (
     }\r
   }\r
 \r
+  mVariableModuleGlobal->MaxVolatileVariableSize = ((PcdGet32 (PcdMaxVolatileVariableSize) != 0) ?\r
+                                                    PcdGet32 (PcdMaxVolatileVariableSize) :\r
+                                                    mVariableModuleGlobal->MaxVariableSize\r
+                                                    );\r
   //\r
   // Allocate memory for volatile variable store, note that there is a scratch space to store scratch data.\r
   //\r
-  ScratchSize = GetNonVolatileMaxVariableSize ();\r
+  ScratchSize = GetMaxVariableSize ();\r
   mVariableModuleGlobal->ScratchBufferSize = ScratchSize;\r
   VolatileVariableStore = AllocateRuntimePool (PcdGet32 (PcdVariableStoreSize) + ScratchSize);\r
   if (VolatileVariableStore == NULL) {\r