SecurityPkg Variable: Implement variable quota management.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16670 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
		| @@ -48,14 +48,6 @@ typedef struct { | |||||||
|   INTERNAL_VAR_CHECK_FUNCTION   CheckFunction; |   INTERNAL_VAR_CHECK_FUNCTION   CheckFunction; | ||||||
| } UEFI_DEFINED_VARIABLE_ENTRY; | } UEFI_DEFINED_VARIABLE_ENTRY; | ||||||
|  |  | ||||||
| typedef struct _EFI_LOAD_OPTION { |  | ||||||
|   UINT32                   Attributes; |  | ||||||
|   UINT16                   FilePathListLength; |  | ||||||
| //CHAR16                   Description[]; |  | ||||||
| //EFI_DEVICE_PATH_PROTOCOL FilePathList[]; |  | ||||||
| //UINT8                    OptionalData[]; |  | ||||||
| } EFI_LOAD_OPTION; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   Internal check for load option. |   Internal check for load option. | ||||||
|  |  | ||||||
| @@ -75,16 +67,16 @@ InternalVarCheckLoadOption ( | |||||||
|   IN VOID                           *Data |   IN VOID                           *Data | ||||||
|   ) |   ) | ||||||
| { | { | ||||||
|   EFI_LOAD_OPTION           *LoadOption; |   UINT16                    FilePathListLength; | ||||||
|   CHAR16                    *Description; |   CHAR16                    *Description; | ||||||
|   EFI_DEVICE_PATH_PROTOCOL  *FilePathList; |   EFI_DEVICE_PATH_PROTOCOL  *FilePathList; | ||||||
|  |  | ||||||
|   LoadOption = (EFI_LOAD_OPTION *) Data; |   FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32))); | ||||||
|  |  | ||||||
|   // |   // | ||||||
|   // Check Description |   // Check Description | ||||||
|   // |   // | ||||||
|   Description = (CHAR16 *) ((UINTN) Data + sizeof (EFI_LOAD_OPTION)); |   Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16)); | ||||||
|   while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) { |   while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) { | ||||||
|     if (*Description == L'\0') { |     if (*Description == L'\0') { | ||||||
|       break; |       break; | ||||||
| @@ -100,16 +92,16 @@ InternalVarCheckLoadOption ( | |||||||
|   // Check FilePathList |   // Check FilePathList | ||||||
|   // |   // | ||||||
|   FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description; |   FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description; | ||||||
|   if ((UINTN) FilePathList > (MAX_ADDRESS - LoadOption->FilePathListLength)) { |   if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) { | ||||||
|     return EFI_INVALID_PARAMETER; |     return EFI_INVALID_PARAMETER; | ||||||
|   } |   } | ||||||
|   if (((UINTN) FilePathList + LoadOption->FilePathListLength) > ((UINTN) Data + DataSize)) { |   if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) { | ||||||
|     return EFI_INVALID_PARAMETER; |     return EFI_INVALID_PARAMETER; | ||||||
|   } |   } | ||||||
|   if (LoadOption->FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { |   if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { | ||||||
|     return EFI_INVALID_PARAMETER; |     return EFI_INVALID_PARAMETER; | ||||||
|   } |   } | ||||||
|   if (!IsDevicePathValid (FilePathList, LoadOption->FilePathListLength)) { |   if (!IsDevicePathValid (FilePathList, FilePathListLength)) { | ||||||
|     return EFI_INVALID_PARAMETER; |     return EFI_INVALID_PARAMETER; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -573,7 +565,7 @@ UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = { | |||||||
|       VAR_CHECK_VARIABLE_PROPERTY_REVISION, |       VAR_CHECK_VARIABLE_PROPERTY_REVISION, | ||||||
|       0, |       0, | ||||||
|       VARIABLE_ATTRIBUTE_NV_BS_RT, |       VARIABLE_ATTRIBUTE_NV_BS_RT, | ||||||
|       sizeof (EFI_LOAD_OPTION), |       sizeof (UINT32) + sizeof (UINT16), | ||||||
|       MAX_UINTN |       MAX_UINTN | ||||||
|     }, |     }, | ||||||
|     InternalVarCheckLoadOption |     InternalVarCheckLoadOption | ||||||
| @@ -584,7 +576,7 @@ UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = { | |||||||
|       VAR_CHECK_VARIABLE_PROPERTY_REVISION, |       VAR_CHECK_VARIABLE_PROPERTY_REVISION, | ||||||
|       0, |       0, | ||||||
|       VARIABLE_ATTRIBUTE_NV_BS_RT, |       VARIABLE_ATTRIBUTE_NV_BS_RT, | ||||||
|       sizeof (EFI_LOAD_OPTION), |       sizeof (UINT32) + sizeof (UINT16), | ||||||
|       MAX_UINTN |       MAX_UINTN | ||||||
|     }, |     }, | ||||||
|     InternalVarCheckLoadOption |     InternalVarCheckLoadOption | ||||||
| @@ -658,8 +650,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = { | |||||||
|       VARIABLE_ATTRIBUTE_NV_BS, |       VARIABLE_ATTRIBUTE_NV_BS, | ||||||
|       sizeof (UINT8), |       sizeof (UINT8), | ||||||
|       sizeof (UINT8) |       sizeof (UINT8) | ||||||
|     }, |     } | ||||||
|     NULL |  | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     &gEfiCustomModeEnableGuid, |     &gEfiCustomModeEnableGuid, | ||||||
| @@ -670,8 +661,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = { | |||||||
|       VARIABLE_ATTRIBUTE_NV_BS, |       VARIABLE_ATTRIBUTE_NV_BS, | ||||||
|       sizeof (UINT8), |       sizeof (UINT8), | ||||||
|       sizeof (UINT8) |       sizeof (UINT8) | ||||||
|     }, |     } | ||||||
|     NULL |  | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     &gEfiVendorKeysNvGuid, |     &gEfiVendorKeysNvGuid, | ||||||
| @@ -682,8 +672,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = { | |||||||
|       VARIABLE_ATTRIBUTE_NV_BS_RT_AT, |       VARIABLE_ATTRIBUTE_NV_BS_RT_AT, | ||||||
|       sizeof (UINT8), |       sizeof (UINT8), | ||||||
|       sizeof (UINT8) |       sizeof (UINT8) | ||||||
|     }, |     } | ||||||
|     NULL |  | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     &gEfiAuthenticatedVariableGuid, |     &gEfiAuthenticatedVariableGuid, | ||||||
| @@ -694,8 +683,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = { | |||||||
|       VARIABLE_ATTRIBUTE_NV_BS_RT_AW, |       VARIABLE_ATTRIBUTE_NV_BS_RT_AW, | ||||||
|       sizeof (UINT8), |       sizeof (UINT8), | ||||||
|       MAX_UINTN |       MAX_UINTN | ||||||
|     }, |     } | ||||||
|     NULL |  | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     &gEfiCertDbGuid, |     &gEfiCertDbGuid, | ||||||
| @@ -706,8 +694,18 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = { | |||||||
|       VARIABLE_ATTRIBUTE_NV_BS_RT_AT, |       VARIABLE_ATTRIBUTE_NV_BS_RT_AT, | ||||||
|       sizeof (UINT32), |       sizeof (UINT32), | ||||||
|       MAX_UINTN |       MAX_UINTN | ||||||
|  |     } | ||||||
|   }, |   }, | ||||||
|     NULL |   { | ||||||
|  |     &gEdkiiVarErrorFlagGuid, | ||||||
|  |     VAR_ERROR_FLAG_NAME, | ||||||
|  |     { | ||||||
|  |       VAR_CHECK_VARIABLE_PROPERTY_REVISION, | ||||||
|  |       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY, | ||||||
|  |       VARIABLE_ATTRIBUTE_NV_BS_RT, | ||||||
|  |       sizeof (VAR_ERROR_FLAG), | ||||||
|  |       sizeof (VAR_ERROR_FLAG) | ||||||
|  |     } | ||||||
|   }, |   }, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -770,7 +768,7 @@ GetUefiDefinedVariableProperty ( | |||||||
|           *VariableProperty = &mGlobalVariableList2[Index].VariableProperty; |           *VariableProperty = &mGlobalVariableList2[Index].VariableProperty; | ||||||
|           return EFI_SUCCESS; |           return EFI_SUCCESS; | ||||||
|         } |         } | ||||||
|       } else { |       } | ||||||
|       if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) { |       if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) { | ||||||
|         if (VarCheckFunction != NULL) { |         if (VarCheckFunction != NULL) { | ||||||
|           *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction; |           *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction; | ||||||
| @@ -779,7 +777,6 @@ GetUefiDefinedVariableProperty ( | |||||||
|         return EFI_SUCCESS; |         return EFI_SUCCESS; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // |     // | ||||||
|     // The variable name is not in the lists. |     // The variable name is not in the lists. | ||||||
| @@ -812,7 +809,6 @@ GetUefiDefinedVariableProperty ( | |||||||
|  |  | ||||||
|   @param[in]  VariableName      Pointer to variable name. |   @param[in]  VariableName      Pointer to variable name. | ||||||
|   @param[in]  VendorGuid        Variable Vendor Guid. |   @param[in]  VendorGuid        Variable Vendor Guid. | ||||||
|   @param[out] VarCheckFunction  Pointer to check function. |  | ||||||
|  |  | ||||||
|   @return Pointer to variable property. |   @return Pointer to variable property. | ||||||
|  |  | ||||||
| @@ -820,17 +816,13 @@ GetUefiDefinedVariableProperty ( | |||||||
| VAR_CHECK_VARIABLE_PROPERTY * | VAR_CHECK_VARIABLE_PROPERTY * | ||||||
| GetVariableDriverVariableProperty ( | GetVariableDriverVariableProperty ( | ||||||
|   IN CHAR16                         *VariableName, |   IN CHAR16                         *VariableName, | ||||||
|   IN EFI_GUID                       *VendorGuid, |   IN EFI_GUID                       *VendorGuid | ||||||
|   OUT INTERNAL_VAR_CHECK_FUNCTION   *VarCheckFunction OPTIONAL |  | ||||||
|   ) |   ) | ||||||
| { | { | ||||||
|   UINTN     Index; |   UINTN     Index; | ||||||
|  |  | ||||||
|   for (Index = 0; Index < sizeof (mVariableDriverVariableList)/sizeof (mVariableDriverVariableList[0]); Index++) { |   for (Index = 0; Index < sizeof (mVariableDriverVariableList)/sizeof (mVariableDriverVariableList[0]); Index++) { | ||||||
|     if ((CompareGuid (mVariableDriverVariableList[Index].Guid, VendorGuid)) && (StrCmp (mVariableDriverVariableList[Index].Name, VariableName) == 0)) { |     if ((CompareGuid (mVariableDriverVariableList[Index].Guid, VendorGuid)) && (StrCmp (mVariableDriverVariableList[Index].Name, VariableName) == 0)) { | ||||||
|       if (VarCheckFunction != NULL) { |  | ||||||
|         *VarCheckFunction = mVariableDriverVariableList[Index].CheckFunction; |  | ||||||
|       } |  | ||||||
|       return &mVariableDriverVariableList[Index].VariableProperty; |       return &mVariableDriverVariableList[Index].VariableProperty; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -881,16 +873,8 @@ InternalVarCheckSetVariableCheck ( | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   Property = NULL; |   Property = NULL; | ||||||
|   Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction); |  | ||||||
|   if (EFI_ERROR (Status)) { |  | ||||||
|     DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName)); |  | ||||||
|     return Status; |  | ||||||
|   } |  | ||||||
|   if (Property == NULL) { |  | ||||||
|     Property = GetVariableDriverVariableProperty (VariableName, VendorGuid, &VarCheckFunction); |  | ||||||
|   } |  | ||||||
|   if (Property == NULL) { |  | ||||||
|   VarCheckFunction = NULL; |   VarCheckFunction = NULL; | ||||||
|  |  | ||||||
|   for ( Link = GetFirstNode (&mVarCheckVariableList) |   for ( Link = GetFirstNode (&mVarCheckVariableList) | ||||||
|       ; !IsNull (&mVarCheckVariableList, Link) |       ; !IsNull (&mVarCheckVariableList, Link) | ||||||
|       ; Link = GetNextNode (&mVarCheckVariableList, Link) |       ; Link = GetNextNode (&mVarCheckVariableList, Link) | ||||||
| @@ -902,25 +886,32 @@ InternalVarCheckSetVariableCheck ( | |||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |   if (Property == NULL) { | ||||||
|  |     Property = GetVariableDriverVariableProperty (VariableName, VendorGuid); | ||||||
|  |   } | ||||||
|  |   if (Property == NULL) { | ||||||
|  |     Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName)); | ||||||
|  |       return Status; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|   if (Property != NULL) { |   if (Property != NULL) { | ||||||
|     if (mEnableLocking && ((Property->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0)) { |     if (mEnableLocking && ((Property->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0)) { | ||||||
|       DEBUG ((EFI_D_INFO, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName)); |       DEBUG ((EFI_D_INFO, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName)); | ||||||
|       return EFI_WRITE_PROTECTED; |       return EFI_WRITE_PROTECTED; | ||||||
|     } |     } | ||||||
|     if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) { |     if (!((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0))) { | ||||||
|       // |       // | ||||||
|       // Do not check delete variable. |       // Not to delete variable. | ||||||
|       // |       // | ||||||
|       return EFI_SUCCESS; |  | ||||||
|     } |  | ||||||
|       if ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes) { |       if ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes) { | ||||||
|       DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName)); |         DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName)); | ||||||
|         return EFI_INVALID_PARAMETER; |         return EFI_INVALID_PARAMETER; | ||||||
|       } |       } | ||||||
|       if (DataSize != 0) { |       if (DataSize != 0) { | ||||||
|         if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) { |         if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) { | ||||||
|         DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName)); |           DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName)); | ||||||
|           return EFI_INVALID_PARAMETER; |           return EFI_INVALID_PARAMETER; | ||||||
|         } |         } | ||||||
|         if (VarCheckFunction != NULL) { |         if (VarCheckFunction != NULL) { | ||||||
| @@ -936,6 +927,7 @@ InternalVarCheckSetVariableCheck ( | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   for (Index = 0; Index < mNumberOfHandler; Index ++) { |   for (Index = 0; Index < mNumberOfHandler; Index ++) { | ||||||
|     Status = mHandlerTable[Index] ( |     Status = mHandlerTable[Index] ( | ||||||
| @@ -1047,18 +1039,20 @@ VarCheckRegisterSetVariableCheckHandler ( | |||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   Internal variable property get. |   Variable property get function. | ||||||
|  |  | ||||||
|   @param[in] Name           Pointer to the variable name. |   @param[in] Name           Pointer to the variable name. | ||||||
|   @param[in] Guid           Pointer to the vendor GUID. |   @param[in] Guid           Pointer to the vendor GUID. | ||||||
|  |   @param[in] WildcardMatch  Try wildcard match or not. | ||||||
|  |  | ||||||
|   @return Pointer to the property of variable specified by the Name and Guid. |   @return Pointer to the property of variable specified by the Name and Guid. | ||||||
|  |  | ||||||
| **/ | **/ | ||||||
| VAR_CHECK_VARIABLE_PROPERTY * | VAR_CHECK_VARIABLE_PROPERTY * | ||||||
| InternalVarCheckVariablePropertyGet ( | VariablePropertyGetFunction ( | ||||||
|   IN CHAR16                 *Name, |   IN CHAR16                 *Name, | ||||||
|   IN EFI_GUID                       *Guid |   IN EFI_GUID               *Guid, | ||||||
|  |   IN BOOLEAN                WildcardMatch | ||||||
|   ) |   ) | ||||||
| { | { | ||||||
|   LIST_ENTRY                    *Link; |   LIST_ENTRY                    *Link; | ||||||
| @@ -1066,14 +1060,6 @@ InternalVarCheckVariablePropertyGet ( | |||||||
|   CHAR16                        *VariableName; |   CHAR16                        *VariableName; | ||||||
|   VAR_CHECK_VARIABLE_PROPERTY   *Property; |   VAR_CHECK_VARIABLE_PROPERTY   *Property; | ||||||
|  |  | ||||||
|   Property = NULL; |  | ||||||
|   GetUefiDefinedVariableProperty (Name, Guid, FALSE, &Property, NULL); |  | ||||||
|   if (Property == NULL) { |  | ||||||
|     Property = GetVariableDriverVariableProperty (Name, Guid, NULL); |  | ||||||
|   } |  | ||||||
|   if (Property != NULL) { |  | ||||||
|     return Property; |  | ||||||
|   } else { |  | ||||||
|   for ( Link = GetFirstNode (&mVarCheckVariableList) |   for ( Link = GetFirstNode (&mVarCheckVariableList) | ||||||
|       ; !IsNull (&mVarCheckVariableList, Link) |       ; !IsNull (&mVarCheckVariableList, Link) | ||||||
|       ; Link = GetNextNode (&mVarCheckVariableList, Link) |       ; Link = GetNextNode (&mVarCheckVariableList, Link) | ||||||
| @@ -1084,9 +1070,13 @@ InternalVarCheckVariablePropertyGet ( | |||||||
|       return &Entry->VariableProperty; |       return &Entry->VariableProperty; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   Property = GetVariableDriverVariableProperty (Name, Guid); | ||||||
|  |   if (Property == NULL) { | ||||||
|  |     GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return NULL; |   return Property; | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -1137,7 +1127,7 @@ VarCheckVariablePropertySet ( | |||||||
|  |  | ||||||
|   AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); |   AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); | ||||||
|  |  | ||||||
|   Property = InternalVarCheckVariablePropertyGet (Name, Guid); |   Property = VariablePropertyGetFunction (Name, Guid, FALSE); | ||||||
|   if (Property != NULL) { |   if (Property != NULL) { | ||||||
|     CopyMem (Property, VariableProperty, sizeof (*VariableProperty)); |     CopyMem (Property, VariableProperty, sizeof (*VariableProperty)); | ||||||
|   } else { |   } else { | ||||||
| @@ -1160,20 +1150,19 @@ Done: | |||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   Variable property get. |   Internal variable property get. | ||||||
|  |  | ||||||
|   @param[in]  Name              Pointer to the variable name. |   @param[in]  Name              Pointer to the variable name. | ||||||
|   @param[in]  Guid              Pointer to the vendor GUID. |   @param[in]  Guid              Pointer to the vendor GUID. | ||||||
|   @param[out] VariableProperty  Pointer to the output variable property. |   @param[out] VariableProperty  Pointer to the output variable property. | ||||||
|  |  | ||||||
|   @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was got successfully. |   @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was got successfully. | ||||||
|   @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string. |  | ||||||
|   @retval EFI_NOT_FOUND         The property of variable specified by the Name and Guid was not found. |   @retval EFI_NOT_FOUND         The property of variable specified by the Name and Guid was not found. | ||||||
|  |  | ||||||
| **/ | **/ | ||||||
| EFI_STATUS | EFI_STATUS | ||||||
| EFIAPI | EFIAPI | ||||||
| VarCheckVariablePropertyGet ( | InternalVarCheckVariablePropertyGet ( | ||||||
|   IN CHAR16                         *Name, |   IN CHAR16                         *Name, | ||||||
|   IN EFI_GUID                       *Guid, |   IN EFI_GUID                       *Guid, | ||||||
|   OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty |   OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty | ||||||
| @@ -1185,19 +1174,9 @@ VarCheckVariablePropertyGet ( | |||||||
|   BOOLEAN                       Found; |   BOOLEAN                       Found; | ||||||
|   VAR_CHECK_VARIABLE_PROPERTY   *Property; |   VAR_CHECK_VARIABLE_PROPERTY   *Property; | ||||||
|  |  | ||||||
|   if (Name == NULL || Name[0] == 0 || Guid == NULL) { |  | ||||||
|     return EFI_INVALID_PARAMETER; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (VariableProperty == NULL) { |  | ||||||
|     return EFI_INVALID_PARAMETER; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   Found = FALSE; |   Found = FALSE; | ||||||
|  |  | ||||||
|   AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); |   Property = VariablePropertyGetFunction (Name, Guid, TRUE); | ||||||
|  |  | ||||||
|   Property = InternalVarCheckVariablePropertyGet (Name, Guid); |  | ||||||
|   if (Property != NULL) { |   if (Property != NULL) { | ||||||
|     CopyMem (VariableProperty, Property, sizeof (*VariableProperty)); |     CopyMem (VariableProperty, Property, sizeof (*VariableProperty)); | ||||||
|     Found = TRUE; |     Found = TRUE; | ||||||
| @@ -1218,8 +1197,45 @@ VarCheckVariablePropertyGet ( | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); |  | ||||||
|  |  | ||||||
|   return (Found ? EFI_SUCCESS : EFI_NOT_FOUND); |   return (Found ? EFI_SUCCESS : EFI_NOT_FOUND); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   Variable property get. | ||||||
|  |  | ||||||
|  |   @param[in]  Name              Pointer to the variable name. | ||||||
|  |   @param[in]  Guid              Pointer to the vendor GUID. | ||||||
|  |   @param[out] VariableProperty  Pointer to the output variable property. | ||||||
|  |  | ||||||
|  |   @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was got successfully. | ||||||
|  |   @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string. | ||||||
|  |   @retval EFI_NOT_FOUND         The property of variable specified by the Name and Guid was not found. | ||||||
|  |  | ||||||
|  | **/ | ||||||
|  | EFI_STATUS | ||||||
|  | EFIAPI | ||||||
|  | VarCheckVariablePropertyGet ( | ||||||
|  |   IN CHAR16                         *Name, | ||||||
|  |   IN EFI_GUID                       *Guid, | ||||||
|  |   OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty | ||||||
|  |   ) | ||||||
|  | { | ||||||
|  |   EFI_STATUS    Status; | ||||||
|  |  | ||||||
|  |   if (Name == NULL || Name[0] == 0 || Guid == NULL) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (VariableProperty == NULL) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); | ||||||
|  |  | ||||||
|  |   Status = InternalVarCheckVariablePropertyGet (Name, Guid, VariableProperty); | ||||||
|  |  | ||||||
|  |   ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); | ||||||
|  |  | ||||||
|  |   return Status; | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -542,6 +542,218 @@ GetEndPointer ( | |||||||
|   return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size); |   return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   Record variable error flag. | ||||||
|  |  | ||||||
|  |   @param[in] Flag               Variable error flag to record. | ||||||
|  |   @param[in] VariableName       Name of variable. | ||||||
|  |   @param[in] VendorGuid         Guid of variable. | ||||||
|  |   @param[in] Attributes         Attributes of the variable. | ||||||
|  |   @param[in] VariableSize       Size of the variable. | ||||||
|  |  | ||||||
|  | **/ | ||||||
|  | VOID | ||||||
|  | RecordVarErrorFlag ( | ||||||
|  |   IN VAR_ERROR_FLAG         Flag, | ||||||
|  |   IN CHAR16                 *VariableName, | ||||||
|  |   IN EFI_GUID               *VendorGuid, | ||||||
|  |   IN UINT32                 Attributes, | ||||||
|  |   IN UINTN                  VariableSize | ||||||
|  |   ) | ||||||
|  | { | ||||||
|  |   EFI_STATUS                Status; | ||||||
|  |   VARIABLE_POINTER_TRACK    Variable; | ||||||
|  |   VAR_ERROR_FLAG            *VarErrFlag; | ||||||
|  |   VAR_ERROR_FLAG            TempFlag; | ||||||
|  |  | ||||||
|  |   DEBUG_CODE ( | ||||||
|  |     DEBUG ((EFI_D_ERROR, "RecordVarErrorFlag (0x%02x) %s:%g - 0x%08x - 0x%x\n", Flag, VariableName, VendorGuid, Attributes, VariableSize)); | ||||||
|  |     if (Flag == VAR_ERROR_FLAG_SYSTEM_ERROR) { | ||||||
|  |       if (AtRuntime ()) { | ||||||
|  |         DEBUG ((EFI_D_ERROR, "CommonRuntimeVariableSpace = 0x%x - CommonVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonRuntimeVariableSpace, mVariableModuleGlobal->CommonVariableTotalSize)); | ||||||
|  |       } else { | ||||||
|  |         DEBUG ((EFI_D_ERROR, "CommonVariableSpace = 0x%x - CommonVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonVariableTotalSize)); | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       DEBUG ((EFI_D_ERROR, "CommonMaxUserVariableSpace = 0x%x - CommonUserVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonMaxUserVariableSpace, mVariableModuleGlobal->CommonUserVariableTotalSize)); | ||||||
|  |     } | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   // | ||||||
|  |   // Record error flag (it should have be initialized). | ||||||
|  |   // | ||||||
|  |   Status = FindVariable ( | ||||||
|  |              VAR_ERROR_FLAG_NAME, | ||||||
|  |              &gEdkiiVarErrorFlagGuid, | ||||||
|  |              &Variable, | ||||||
|  |              &mVariableModuleGlobal->VariableGlobal, | ||||||
|  |              FALSE | ||||||
|  |              ); | ||||||
|  |   if (!EFI_ERROR (Status)) { | ||||||
|  |     VarErrFlag = (VAR_ERROR_FLAG *) GetVariableDataPtr (Variable.CurrPtr); | ||||||
|  |     TempFlag = *VarErrFlag; | ||||||
|  |     TempFlag &= Flag; | ||||||
|  |     if (TempFlag == *VarErrFlag) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     Status = UpdateVariableStore ( | ||||||
|  |                &mVariableModuleGlobal->VariableGlobal, | ||||||
|  |                FALSE, | ||||||
|  |                FALSE, | ||||||
|  |                mVariableModuleGlobal->FvbInstance, | ||||||
|  |                (UINTN) VarErrFlag - (UINTN) mNvVariableCache + (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, | ||||||
|  |                sizeof (TempFlag), | ||||||
|  |                &TempFlag | ||||||
|  |                ); | ||||||
|  |     if (!EFI_ERROR (Status)) { | ||||||
|  |       // | ||||||
|  |       // Update the data in NV cache. | ||||||
|  |       // | ||||||
|  |       *VarErrFlag = Flag; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   Initialize variable error flag. | ||||||
|  |  | ||||||
|  |   Before EndOfDxe, the variable indicates the last boot variable error flag, | ||||||
|  |   then it means the last boot variable error flag must be got before EndOfDxe. | ||||||
|  |   After EndOfDxe, the variable indicates the current boot variable error flag, | ||||||
|  |   then it means the current boot variable error flag must be got after EndOfDxe. | ||||||
|  |  | ||||||
|  | **/ | ||||||
|  | VOID | ||||||
|  | InitializeVarErrorFlag ( | ||||||
|  |   VOID | ||||||
|  |   ) | ||||||
|  | { | ||||||
|  |   EFI_STATUS                Status; | ||||||
|  |   VARIABLE_POINTER_TRACK    Variable; | ||||||
|  |   VAR_ERROR_FLAG            Flag; | ||||||
|  |   VAR_ERROR_FLAG            VarErrFlag; | ||||||
|  |  | ||||||
|  |   if (!mEndOfDxe) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Flag = VAR_ERROR_FLAG_NO_ERROR; | ||||||
|  |   DEBUG ((EFI_D_INFO, "Initialize variable error flag (%02x)\n", Flag)); | ||||||
|  |  | ||||||
|  |   Status = FindVariable ( | ||||||
|  |              VAR_ERROR_FLAG_NAME, | ||||||
|  |              &gEdkiiVarErrorFlagGuid, | ||||||
|  |              &Variable, | ||||||
|  |              &mVariableModuleGlobal->VariableGlobal, | ||||||
|  |              FALSE | ||||||
|  |              ); | ||||||
|  |   if (!EFI_ERROR (Status)) { | ||||||
|  |     VarErrFlag = *((VAR_ERROR_FLAG *) GetVariableDataPtr (Variable.CurrPtr)); | ||||||
|  |     if (VarErrFlag == Flag) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   UpdateVariable ( | ||||||
|  |     VAR_ERROR_FLAG_NAME, | ||||||
|  |     &gEdkiiVarErrorFlagGuid, | ||||||
|  |     &Flag, | ||||||
|  |     sizeof (Flag), | ||||||
|  |     VARIABLE_ATTRIBUTE_NV_BS_RT, | ||||||
|  |     0, | ||||||
|  |     0, | ||||||
|  |     &Variable, | ||||||
|  |     NULL | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   Is user variable? | ||||||
|  |  | ||||||
|  |   @param[in] Variable   Pointer to variable header. | ||||||
|  |  | ||||||
|  |   @retval TRUE          User variable. | ||||||
|  |   @retval FALSE         System variable. | ||||||
|  |  | ||||||
|  | **/ | ||||||
|  | BOOLEAN | ||||||
|  | IsUserVariable ( | ||||||
|  |   IN VARIABLE_HEADER    *Variable | ||||||
|  |   ) | ||||||
|  | { | ||||||
|  |   VAR_CHECK_VARIABLE_PROPERTY   Property; | ||||||
|  |  | ||||||
|  |   // | ||||||
|  |   // Only after End Of Dxe, the variables belong to system variable are fixed. | ||||||
|  |   // If PcdMaxUserNvStorageVariableSize is 0, it means user variable share the same NV storage with system variable, | ||||||
|  |   // then no need to check if the variable is user variable or not specially. | ||||||
|  |   // | ||||||
|  |   if (mEndOfDxe && (mVariableModuleGlobal->CommonMaxUserVariableSpace != mVariableModuleGlobal->CommonVariableSpace)) { | ||||||
|  |     if (InternalVarCheckVariablePropertyGet (GetVariableNamePtr (Variable), &Variable->VendorGuid, &Property) == EFI_NOT_FOUND) { | ||||||
|  |       return TRUE; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return FALSE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   Calculate common user variable total size. | ||||||
|  |  | ||||||
|  | **/ | ||||||
|  | VOID | ||||||
|  | CalculateCommonUserVariableTotalSize ( | ||||||
|  |   VOID | ||||||
|  |   ) | ||||||
|  | { | ||||||
|  |   VARIABLE_HEADER               *Variable; | ||||||
|  |   VARIABLE_HEADER               *NextVariable; | ||||||
|  |   UINTN                         VariableSize; | ||||||
|  |   VAR_CHECK_VARIABLE_PROPERTY   Property; | ||||||
|  |  | ||||||
|  |   // | ||||||
|  |   // Only after End Of Dxe, the variables belong to system variable are fixed. | ||||||
|  |   // If PcdMaxUserNvStorageVariableSize is 0, it means user variable share the same NV storage with system variable, | ||||||
|  |   // then no need to calculate the common user variable total size specially. | ||||||
|  |   // | ||||||
|  |   if (mEndOfDxe && (mVariableModuleGlobal->CommonMaxUserVariableSpace != mVariableModuleGlobal->CommonVariableSpace)) { | ||||||
|  |     Variable = GetStartPointer (mNvVariableCache); | ||||||
|  |     while (IsValidVariableHeader (Variable, GetEndPointer (mNvVariableCache))) { | ||||||
|  |       NextVariable = GetNextVariablePtr (Variable); | ||||||
|  |       VariableSize = (UINTN) NextVariable - (UINTN) Variable; | ||||||
|  |       if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { | ||||||
|  |         if (InternalVarCheckVariablePropertyGet (GetVariableNamePtr (Variable), &Variable->VendorGuid, &Property) == EFI_NOT_FOUND) { | ||||||
|  |           // | ||||||
|  |           // No property, it is user variable. | ||||||
|  |           // | ||||||
|  |           mVariableModuleGlobal->CommonUserVariableTotalSize += VariableSize; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       Variable = NextVariable; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   Initialize variable quota. | ||||||
|  |  | ||||||
|  | **/ | ||||||
|  | VOID | ||||||
|  | InitializeVariableQuota ( | ||||||
|  |   VOID | ||||||
|  |   ) | ||||||
|  | { | ||||||
|  |   STATIC BOOLEAN    Initialized; | ||||||
|  |  | ||||||
|  |   if (!mEndOfDxe || Initialized) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   Initialized = TRUE; | ||||||
|  |  | ||||||
|  |   InitializeVarErrorFlag (); | ||||||
|  |   CalculateCommonUserVariableTotalSize (); | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  |  | ||||||
|   Check the PubKeyIndex is a valid key or not. |   Check the PubKeyIndex is a valid key or not. | ||||||
| @@ -726,6 +938,7 @@ Reclaim ( | |||||||
|   BOOLEAN               FoundAdded; |   BOOLEAN               FoundAdded; | ||||||
|   EFI_STATUS            Status; |   EFI_STATUS            Status; | ||||||
|   UINTN                 CommonVariableTotalSize; |   UINTN                 CommonVariableTotalSize; | ||||||
|  |   UINTN                 CommonUserVariableTotalSize; | ||||||
|   UINTN                 HwErrVariableTotalSize; |   UINTN                 HwErrVariableTotalSize; | ||||||
|   UINT32                *NewPubKeyIndex; |   UINT32                *NewPubKeyIndex; | ||||||
|   UINT8                 *NewPubKeyStore; |   UINT8                 *NewPubKeyStore; | ||||||
| @@ -744,6 +957,7 @@ Reclaim ( | |||||||
|   VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase); |   VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase); | ||||||
|  |  | ||||||
|   CommonVariableTotalSize = 0; |   CommonVariableTotalSize = 0; | ||||||
|  |   CommonUserVariableTotalSize = 0; | ||||||
|   HwErrVariableTotalSize  = 0; |   HwErrVariableTotalSize  = 0; | ||||||
|   NewPubKeyIndex = NULL; |   NewPubKeyIndex = NULL; | ||||||
|   NewPubKeyStore = NULL; |   NewPubKeyStore = NULL; | ||||||
| @@ -845,6 +1059,9 @@ Reclaim ( | |||||||
|           HwErrVariableTotalSize += VariableSize; |           HwErrVariableTotalSize += VariableSize; | ||||||
|         } else if ((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; |           CommonVariableTotalSize += VariableSize; | ||||||
|  |           if (IsUserVariable (Variable)) { | ||||||
|  |             CommonUserVariableTotalSize += VariableSize; | ||||||
|  |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       Variable = NextVariable; |       Variable = NextVariable; | ||||||
| @@ -865,6 +1082,9 @@ Reclaim ( | |||||||
|     CopyMem (GetVariableDataPtr (Variable), NewPubKeyStore, NewPubKeySize); |     CopyMem (GetVariableDataPtr (Variable), NewPubKeyStore, NewPubKeySize); | ||||||
|     CurrPtr = (UINT8*) GetNextVariablePtr (Variable); |     CurrPtr = (UINT8*) GetNextVariablePtr (Variable); | ||||||
|     CommonVariableTotalSize += (UINTN) CurrPtr - (UINTN) Variable; |     CommonVariableTotalSize += (UINTN) CurrPtr - (UINTN) Variable; | ||||||
|  |     if (IsUserVariable (Variable)) { | ||||||
|  |       CommonUserVariableTotalSize += (UINTN) CurrPtr - (UINTN) Variable; | ||||||
|  |     } | ||||||
|   } else { |   } else { | ||||||
|     // |     // | ||||||
|     // Reinstall all ADDED variables as long as they are not identical to Updating Variable. |     // Reinstall all ADDED variables as long as they are not identical to Updating Variable. | ||||||
| @@ -880,6 +1100,9 @@ Reclaim ( | |||||||
|           HwErrVariableTotalSize += VariableSize; |           HwErrVariableTotalSize += VariableSize; | ||||||
|         } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { |         } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { | ||||||
|           CommonVariableTotalSize += VariableSize; |           CommonVariableTotalSize += VariableSize; | ||||||
|  |           if (IsUserVariable (Variable)) { | ||||||
|  |             CommonUserVariableTotalSize += VariableSize; | ||||||
|  |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       Variable = NextVariable; |       Variable = NextVariable; | ||||||
| @@ -928,6 +1151,9 @@ Reclaim ( | |||||||
|             HwErrVariableTotalSize += VariableSize; |             HwErrVariableTotalSize += VariableSize; | ||||||
|           } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { |           } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { | ||||||
|             CommonVariableTotalSize += VariableSize; |             CommonVariableTotalSize += VariableSize; | ||||||
|  |             if (IsUserVariable (Variable)) { | ||||||
|  |               CommonUserVariableTotalSize += VariableSize; | ||||||
|  |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @@ -951,9 +1177,13 @@ Reclaim ( | |||||||
|           HwErrVariableTotalSize += NewVariableSize; |           HwErrVariableTotalSize += NewVariableSize; | ||||||
|         } else if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { |         } else if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { | ||||||
|           CommonVariableTotalSize += NewVariableSize; |           CommonVariableTotalSize += NewVariableSize; | ||||||
|  |           if (IsUserVariable (NewVariable)) { | ||||||
|  |             CommonUserVariableTotalSize += NewVariableSize; | ||||||
|  |           } | ||||||
|         } |         } | ||||||
|         if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) || |         if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) || | ||||||
|             (CommonVariableTotalSize > VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize))) { |             (CommonVariableTotalSize > mVariableModuleGlobal->CommonVariableSpace) || | ||||||
|  |             (CommonUserVariableTotalSize > mVariableModuleGlobal->CommonMaxUserVariableSpace)) { | ||||||
|           // |           // | ||||||
|           // No enough space to store the new variable by NV or NV+HR attribute. |           // No enough space to store the new variable by NV or NV+HR attribute. | ||||||
|           // |           // | ||||||
| @@ -992,19 +1222,24 @@ Reclaim ( | |||||||
|       *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); |       *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); | ||||||
|       mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize; |       mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize; | ||||||
|       mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize; |       mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize; | ||||||
|  |       mVariableModuleGlobal->CommonUserVariableTotalSize = CommonUserVariableTotalSize; | ||||||
|     } else { |     } else { | ||||||
|       NextVariable  = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); |       Variable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); | ||||||
|       while (IsValidVariableHeader (NextVariable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase))) { |       while (IsValidVariableHeader (Variable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase))) { | ||||||
|         VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); |         NextVariable = GetNextVariablePtr (Variable); | ||||||
|  |         VariableSize = (UINTN) NextVariable - (UINTN) Variable; | ||||||
|         if ((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) { | ||||||
|           mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); |           mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize; | ||||||
|         } else if ((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) { | ||||||
|           mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); |           mVariableModuleGlobal->CommonVariableTotalSize += VariableSize; | ||||||
|  |           if (IsUserVariable (Variable)) { | ||||||
|  |             mVariableModuleGlobal->CommonUserVariableTotalSize += VariableSize; | ||||||
|  |           } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         NextVariable = GetNextVariablePtr (NextVariable); |         Variable = NextVariable; | ||||||
|       } |       } | ||||||
|       *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase; |       *LastVariableOffset = (UINTN) Variable - (UINTN) VariableBase; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1875,7 +2110,6 @@ UpdateVariable ( | |||||||
|   VARIABLE_HEADER                     *NextVariable; |   VARIABLE_HEADER                     *NextVariable; | ||||||
|   UINTN                               ScratchSize; |   UINTN                               ScratchSize; | ||||||
|   UINTN                               MaxDataSize; |   UINTN                               MaxDataSize; | ||||||
|   UINTN                               NonVolatileVarableStoreSize; |  | ||||||
|   UINTN                               VarNameOffset; |   UINTN                               VarNameOffset; | ||||||
|   UINTN                               VarDataOffset; |   UINTN                               VarDataOffset; | ||||||
|   UINTN                               VarNameSize; |   UINTN                               VarNameSize; | ||||||
| @@ -1891,6 +2125,8 @@ UpdateVariable ( | |||||||
|   UINTN                               MergedBufSize; |   UINTN                               MergedBufSize; | ||||||
|   BOOLEAN                             DataReady; |   BOOLEAN                             DataReady; | ||||||
|   UINTN                               DataOffset; |   UINTN                               DataOffset; | ||||||
|  |   BOOLEAN                             IsCommonVariable; | ||||||
|  |   BOOLEAN                             IsCommonUserVariable; | ||||||
|  |  | ||||||
|   if (mVariableModuleGlobal->FvbInstance == NULL) { |   if (mVariableModuleGlobal->FvbInstance == NULL) { | ||||||
|     // |     // | ||||||
| @@ -2252,12 +2488,25 @@ UpdateVariable ( | |||||||
|     // Create a nonvolatile variable. |     // Create a nonvolatile variable. | ||||||
|     // |     // | ||||||
|     Volatile = FALSE; |     Volatile = FALSE; | ||||||
|     NonVolatileVarableStoreSize = ((VARIABLE_STORE_HEADER *)(UINTN)(mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase))->Size; |  | ||||||
|  |     IsCommonVariable = FALSE; | ||||||
|  |     IsCommonUserVariable = FALSE; | ||||||
|  |     if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) { | ||||||
|  |       IsCommonVariable = TRUE; | ||||||
|  |       IsCommonUserVariable = IsUserVariable (NextVariable); | ||||||
|  |     } | ||||||
|     if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) |     if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) | ||||||
|       && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize))) |       && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize))) | ||||||
|       || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) |       || (IsCommonVariable && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonVariableSpace)) | ||||||
|       && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) { |       || (IsCommonVariable && AtRuntime () && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonRuntimeVariableSpace)) | ||||||
|  |       || (IsCommonUserVariable && ((VarSize + mVariableModuleGlobal->CommonUserVariableTotalSize) > mVariableModuleGlobal->CommonMaxUserVariableSpace))) { | ||||||
|       if (AtRuntime ()) { |       if (AtRuntime ()) { | ||||||
|  |         if (IsCommonUserVariable && ((VarSize + mVariableModuleGlobal->CommonUserVariableTotalSize) > mVariableModuleGlobal->CommonMaxUserVariableSpace)) { | ||||||
|  |           RecordVarErrorFlag (VAR_ERROR_FLAG_USER_ERROR, VariableName, VendorGuid, Attributes, VarSize); | ||||||
|  |         } | ||||||
|  |         if (IsCommonVariable && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonRuntimeVariableSpace)) { | ||||||
|  |           RecordVarErrorFlag (VAR_ERROR_FLAG_SYSTEM_ERROR, VariableName, VendorGuid, Attributes, VarSize); | ||||||
|  |         } | ||||||
|         Status = EFI_OUT_OF_RESOURCES; |         Status = EFI_OUT_OF_RESOURCES; | ||||||
|         goto Done; |         goto Done; | ||||||
|       } |       } | ||||||
| @@ -2283,6 +2532,13 @@ UpdateVariable ( | |||||||
|         } |         } | ||||||
|         UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, FALSE, FALSE); |         UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, FALSE, FALSE); | ||||||
|         FlushHobVariableToFlash (VariableName, VendorGuid); |         FlushHobVariableToFlash (VariableName, VendorGuid); | ||||||
|  |       } else { | ||||||
|  |         if (IsCommonUserVariable && ((VarSize + mVariableModuleGlobal->CommonUserVariableTotalSize) > mVariableModuleGlobal->CommonMaxUserVariableSpace)) { | ||||||
|  |           RecordVarErrorFlag (VAR_ERROR_FLAG_USER_ERROR, VariableName, VendorGuid, Attributes, VarSize); | ||||||
|  |         } | ||||||
|  |         if (IsCommonVariable && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonVariableSpace)) { | ||||||
|  |           RecordVarErrorFlag (VAR_ERROR_FLAG_SYSTEM_ERROR, VariableName, VendorGuid, Attributes, VarSize); | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|       goto Done; |       goto Done; | ||||||
|     } |     } | ||||||
| @@ -2368,6 +2624,9 @@ UpdateVariable ( | |||||||
|       mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VarSize); |       mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VarSize); | ||||||
|     } else { |     } else { | ||||||
|       mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VarSize); |       mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VarSize); | ||||||
|  |       if (IsCommonUserVariable) { | ||||||
|  |         mVariableModuleGlobal->CommonUserVariableTotalSize += HEADER_ALIGN (VarSize); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|     // |     // | ||||||
|     // update the memory copy of Flash region. |     // update the memory copy of Flash region. | ||||||
| @@ -3024,7 +3283,7 @@ VariableServiceSetVariable ( | |||||||
|       // 2. The only attribute differing is EFI_VARIABLE_APPEND_WRITE |       // 2. The only attribute differing is EFI_VARIABLE_APPEND_WRITE | ||||||
|       // |       // | ||||||
|       Status = EFI_INVALID_PARAMETER; |       Status = EFI_INVALID_PARAMETER; | ||||||
|       DEBUG ((EFI_D_INFO, "[Variable]: Rewritten a preexisting variable with different attributes - %g:%s\n", VendorGuid, VariableName)); |       DEBUG ((EFI_D_INFO, "[Variable]: Rewritten a preexisting variable(0x%08x) with different attributes(0x%08x) - %g:%s\n", Variable.CurrPtr->Attributes, Attributes, VendorGuid, VariableName)); | ||||||
|       goto Done; |       goto Done; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -3145,8 +3404,11 @@ VariableServiceQueryVariableInfoInternal ( | |||||||
|     *MaximumVariableSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER); |     *MaximumVariableSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER); | ||||||
|   } else { |   } else { | ||||||
|     if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) { |     if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) { | ||||||
|       ASSERT (PcdGet32 (PcdHwErrStorageSize) < VariableStoreHeader->Size); |       if (AtRuntime ()) { | ||||||
|       *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize); |         *MaximumVariableStorageSize = mVariableModuleGlobal->CommonRuntimeVariableSpace; | ||||||
|  |       } else { | ||||||
|  |         *MaximumVariableStorageSize = mVariableModuleGlobal->CommonVariableSpace; | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // |     // | ||||||
| @@ -3222,9 +3484,13 @@ VariableServiceQueryVariableInfoInternal ( | |||||||
|  |  | ||||||
|   if ((Attributes  & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD){ |   if ((Attributes  & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD){ | ||||||
|     *RemainingVariableStorageSize = *MaximumVariableStorageSize - HwErrVariableTotalSize; |     *RemainingVariableStorageSize = *MaximumVariableStorageSize - HwErrVariableTotalSize; | ||||||
|  |   } else { | ||||||
|  |     if (*MaximumVariableStorageSize < CommonVariableTotalSize) { | ||||||
|  |       *RemainingVariableStorageSize = 0; | ||||||
|     } else { |     } else { | ||||||
|       *RemainingVariableStorageSize = *MaximumVariableStorageSize - CommonVariableTotalSize; |       *RemainingVariableStorageSize = *MaximumVariableStorageSize - CommonVariableTotalSize; | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   if (*RemainingVariableStorageSize < sizeof (VARIABLE_HEADER)) { |   if (*RemainingVariableStorageSize < sizeof (VARIABLE_HEADER)) { | ||||||
|     *MaximumVariableSize = 0; |     *MaximumVariableSize = 0; | ||||||
| @@ -3271,7 +3537,7 @@ VariableServiceQueryVariableInfo ( | |||||||
|     return EFI_INVALID_PARAMETER; |     return EFI_INVALID_PARAMETER; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) { |   if ((Attributes & VARIABLE_ATTRIBUTE_NV_BS_RT_AT_HR_AW) == 0) { | ||||||
|     // |     // | ||||||
|     // Make sure the Attributes combination is supported by the platform. |     // Make sure the Attributes combination is supported by the platform. | ||||||
|     // |     // | ||||||
| @@ -3319,21 +3585,22 @@ ReclaimForOS( | |||||||
|   ) |   ) | ||||||
| { | { | ||||||
|   EFI_STATUS                     Status; |   EFI_STATUS                     Status; | ||||||
|   UINTN                          CommonVariableSpace; |   UINTN                          RemainingCommonRuntimeVariableSpace; | ||||||
|   UINTN                          RemainingCommonVariableSpace; |  | ||||||
|   UINTN                          RemainingHwErrVariableSpace; |   UINTN                          RemainingHwErrVariableSpace; | ||||||
|  |  | ||||||
|   Status  = EFI_SUCCESS; |   Status  = EFI_SUCCESS; | ||||||
|  |  | ||||||
|   CommonVariableSpace = ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase)))->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32(PcdHwErrStorageSize); //Allowable max size of common variable storage space |   if (mVariableModuleGlobal->CommonRuntimeVariableSpace < mVariableModuleGlobal->CommonVariableTotalSize) { | ||||||
|  |     RemainingCommonRuntimeVariableSpace = 0; | ||||||
|   RemainingCommonVariableSpace = CommonVariableSpace - mVariableModuleGlobal->CommonVariableTotalSize; |   } else { | ||||||
|  |     RemainingCommonRuntimeVariableSpace = mVariableModuleGlobal->CommonRuntimeVariableSpace - mVariableModuleGlobal->CommonVariableTotalSize; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   RemainingHwErrVariableSpace = PcdGet32 (PcdHwErrStorageSize) - mVariableModuleGlobal->HwErrVariableTotalSize; |   RemainingHwErrVariableSpace = PcdGet32 (PcdHwErrStorageSize) - mVariableModuleGlobal->HwErrVariableTotalSize; | ||||||
|   // |   // | ||||||
|   // Check if the free area is blow a threshold. |   // Check if the free area is below a threshold. | ||||||
|   // |   // | ||||||
|   if ((RemainingCommonVariableSpace < PcdGet32 (PcdMaxVariableSize)) |   if ((RemainingCommonRuntimeVariableSpace < PcdGet32 (PcdMaxVariableSize)) | ||||||
|     || ((PcdGet32 (PcdHwErrStorageSize) != 0) && |     || ((PcdGet32 (PcdHwErrStorageSize) != 0) && | ||||||
|        (RemainingHwErrVariableSpace < PcdGet32 (PcdMaxHardwareErrorVariableSize)))){ |        (RemainingHwErrVariableSpace < PcdGet32 (PcdMaxHardwareErrorVariableSize)))){ | ||||||
|     Status = Reclaim ( |     Status = Reclaim ( | ||||||
| @@ -3363,6 +3630,7 @@ InitNonVolatileVariableStore ( | |||||||
|   ) |   ) | ||||||
| { | { | ||||||
|   EFI_FIRMWARE_VOLUME_HEADER            *FvHeader; |   EFI_FIRMWARE_VOLUME_HEADER            *FvHeader; | ||||||
|  |   VARIABLE_HEADER                       *Variable; | ||||||
|   VARIABLE_HEADER                       *NextVariable; |   VARIABLE_HEADER                       *NextVariable; | ||||||
|   EFI_PHYSICAL_ADDRESS                  VariableStoreBase; |   EFI_PHYSICAL_ADDRESS                  VariableStoreBase; | ||||||
|   UINT64                                VariableStoreLength; |   UINT64                                VariableStoreLength; | ||||||
| @@ -3374,17 +3642,12 @@ InitNonVolatileVariableStore ( | |||||||
|   FAULT_TOLERANT_WRITE_LAST_WRITE_DATA  *FtwLastWriteData; |   FAULT_TOLERANT_WRITE_LAST_WRITE_DATA  *FtwLastWriteData; | ||||||
|   UINT32                                BackUpOffset; |   UINT32                                BackUpOffset; | ||||||
|   UINT32                                BackUpSize; |   UINT32                                BackUpSize; | ||||||
|  |   UINT32                                HwErrStorageSize; | ||||||
|  |   UINT32                                MaxUserNvVariableSpaceSize; | ||||||
|  |   UINT32                                BoottimeReservedNvVariableSpaceSize; | ||||||
|  |  | ||||||
|   mVariableModuleGlobal->FvbInstance = NULL; |   mVariableModuleGlobal->FvbInstance = NULL; | ||||||
|  |  | ||||||
|   // |  | ||||||
|   // Note that in EdkII variable driver implementation, Hardware Error Record type variable |  | ||||||
|   // is stored with common variable in the same NV region. So the platform integrator should |  | ||||||
|   // ensure that the value of PcdHwErrStorageSize is less than or equal to the value of |  | ||||||
|   // PcdFlashNvStorageVariableSize. |  | ||||||
|   // |  | ||||||
|   ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdFlashNvStorageVariableSize)); |  | ||||||
|  |  | ||||||
|   // |   // | ||||||
|   // Allocate runtime memory used for a memory copy of the FLASH region. |   // Allocate runtime memory used for a memory copy of the FLASH region. | ||||||
|   // Keep the memory and the FLASH in sync as updates occur. |   // Keep the memory and the FLASH in sync as updates occur. | ||||||
| @@ -3454,6 +3717,37 @@ InitNonVolatileVariableStore ( | |||||||
|   } |   } | ||||||
|   ASSERT(mNvVariableCache->Size == VariableStoreLength); |   ASSERT(mNvVariableCache->Size == VariableStoreLength); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   ASSERT (sizeof (VARIABLE_STORE_HEADER) <= VariableStoreLength); | ||||||
|  |  | ||||||
|  |   HwErrStorageSize = PcdGet32 (PcdHwErrStorageSize); | ||||||
|  |   MaxUserNvVariableSpaceSize = PcdGet32 (PcdMaxUserNvVariableSpaceSize); | ||||||
|  |   BoottimeReservedNvVariableSpaceSize = PcdGet32 (PcdBoottimeReservedNvVariableSpaceSize); | ||||||
|  |  | ||||||
|  |   // | ||||||
|  |   // Note that in EdkII variable driver implementation, Hardware Error Record type variable | ||||||
|  |   // is stored with common variable in the same NV region. So the platform integrator should | ||||||
|  |   // ensure that the value of PcdHwErrStorageSize is less than the value of | ||||||
|  |   // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)). | ||||||
|  |   // | ||||||
|  |   ASSERT (HwErrStorageSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER))); | ||||||
|  |   // | ||||||
|  |   // Ensure that the value of PcdMaxUserNvVariableSpaceSize is less than the value of | ||||||
|  |   // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize). | ||||||
|  |   // | ||||||
|  |   ASSERT (MaxUserNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize)); | ||||||
|  |   // | ||||||
|  |   // Ensure that the value of PcdBoottimeReservedNvVariableSpaceSize is less than the value of | ||||||
|  |   // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize). | ||||||
|  |   // | ||||||
|  |   ASSERT (BoottimeReservedNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize)); | ||||||
|  |  | ||||||
|  |   mVariableModuleGlobal->CommonVariableSpace = ((UINTN) VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize); | ||||||
|  |   mVariableModuleGlobal->CommonMaxUserVariableSpace = ((MaxUserNvVariableSpaceSize != 0) ? MaxUserNvVariableSpaceSize : mVariableModuleGlobal->CommonVariableSpace); | ||||||
|  |   mVariableModuleGlobal->CommonRuntimeVariableSpace = mVariableModuleGlobal->CommonVariableSpace - BoottimeReservedNvVariableSpaceSize; | ||||||
|  |  | ||||||
|  |   DEBUG ((EFI_D_INFO, "Variable driver common space: 0x%x 0x%x 0x%x\n", mVariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonMaxUserVariableSpace, mVariableModuleGlobal->CommonRuntimeVariableSpace)); | ||||||
|  |  | ||||||
|   // |   // | ||||||
|   // The max variable or hardware error variable size should be < variable store size. |   // The max variable or hardware error variable size should be < variable store size. | ||||||
|   // |   // | ||||||
| @@ -3462,18 +3756,19 @@ InitNonVolatileVariableStore ( | |||||||
|   // |   // | ||||||
|   // Parse non-volatile variable data and get last variable offset. |   // Parse non-volatile variable data and get last variable offset. | ||||||
|   // |   // | ||||||
|   NextVariable  = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase); |   Variable  = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase); | ||||||
|   while (IsValidVariableHeader (NextVariable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase))) { |   while (IsValidVariableHeader (Variable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase))) { | ||||||
|     VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); |     NextVariable = GetNextVariablePtr (Variable); | ||||||
|     if ((NextVariable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { |     VariableSize = (UINTN) NextVariable - (UINTN) Variable; | ||||||
|       mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); |     if ((Variable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { | ||||||
|  |       mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize; | ||||||
|     } else { |     } else { | ||||||
|       mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); |       mVariableModuleGlobal->CommonVariableTotalSize += VariableSize; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     NextVariable = GetNextVariablePtr (NextVariable); |     Variable = NextVariable; | ||||||
|   } |   } | ||||||
|   mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) VariableStoreBase; |   mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) Variable - (UINTN) VariableStoreBase; | ||||||
|  |  | ||||||
|   return EFI_SUCCESS; |   return EFI_SUCCESS; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -44,6 +44,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |||||||
| #include <Guid/SystemNvDataGuid.h> | #include <Guid/SystemNvDataGuid.h> | ||||||
| #include <Guid/FaultTolerantWrite.h> | #include <Guid/FaultTolerantWrite.h> | ||||||
| #include <Guid/HardwareErrorVariable.h> | #include <Guid/HardwareErrorVariable.h> | ||||||
|  | #include <Guid/VarErrorFlag.h> | ||||||
|  |  | ||||||
| #define EFI_VARIABLE_ATTRIBUTES_MASK (EFI_VARIABLE_NON_VOLATILE | \ | #define EFI_VARIABLE_ATTRIBUTES_MASK (EFI_VARIABLE_NON_VOLATILE | \ | ||||||
|                                       EFI_VARIABLE_BOOTSERVICE_ACCESS | \ |                                       EFI_VARIABLE_BOOTSERVICE_ACCESS | \ | ||||||
| @@ -59,6 +60,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |||||||
| #define VARIABLE_ATTRIBUTE_NV_BS_RT_AT  (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) | #define VARIABLE_ATTRIBUTE_NV_BS_RT_AT  (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) | ||||||
| #define VARIABLE_ATTRIBUTE_NV_BS_RT_HR  (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_HARDWARE_ERROR_RECORD) | #define VARIABLE_ATTRIBUTE_NV_BS_RT_HR  (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_HARDWARE_ERROR_RECORD) | ||||||
| #define VARIABLE_ATTRIBUTE_NV_BS_RT_AW  (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) | #define VARIABLE_ATTRIBUTE_NV_BS_RT_AW  (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) | ||||||
|  | #define VARIABLE_ATTRIBUTE_NV_BS_RT_AT_HR_AW  (VARIABLE_ATTRIBUTE_NV_BS_RT_AT | EFI_VARIABLE_HARDWARE_ERROR_RECORD | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) | ||||||
|  |  | ||||||
| /// | /// | ||||||
| /// The size of a 3 character ISO639 language code. | /// The size of a 3 character ISO639 language code. | ||||||
| @@ -98,7 +100,11 @@ typedef struct { | |||||||
|   VARIABLE_GLOBAL VariableGlobal; |   VARIABLE_GLOBAL VariableGlobal; | ||||||
|   UINTN           VolatileLastVariableOffset; |   UINTN           VolatileLastVariableOffset; | ||||||
|   UINTN           NonVolatileLastVariableOffset; |   UINTN           NonVolatileLastVariableOffset; | ||||||
|  |   UINTN           CommonVariableSpace; | ||||||
|  |   UINTN           CommonMaxUserVariableSpace; | ||||||
|  |   UINTN           CommonRuntimeVariableSpace; | ||||||
|   UINTN           CommonVariableTotalSize; |   UINTN           CommonVariableTotalSize; | ||||||
|  |   UINTN           CommonUserVariableTotalSize; | ||||||
|   UINTN           HwErrVariableTotalSize; |   UINTN           HwErrVariableTotalSize; | ||||||
|   CHAR8           *PlatformLangCodes; |   CHAR8           *PlatformLangCodes; | ||||||
|   CHAR8           *LangCodes; |   CHAR8           *LangCodes; | ||||||
| @@ -735,6 +741,25 @@ VarCheckRegisterSetVariableCheckHandler ( | |||||||
|   IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER   Handler |   IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER   Handler | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   Internal variable property get. | ||||||
|  |  | ||||||
|  |   @param[in]  Name              Pointer to the variable name. | ||||||
|  |   @param[in]  Guid              Pointer to the vendor GUID. | ||||||
|  |   @param[out] VariableProperty  Pointer to the output variable property. | ||||||
|  |  | ||||||
|  |   @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was got successfully. | ||||||
|  |   @retval EFI_NOT_FOUND         The property of variable specified by the Name and Guid was not found. | ||||||
|  |  | ||||||
|  | **/ | ||||||
|  | EFI_STATUS | ||||||
|  | EFIAPI | ||||||
|  | InternalVarCheckVariablePropertyGet ( | ||||||
|  |   IN CHAR16                         *Name, | ||||||
|  |   IN EFI_GUID                       *Guid, | ||||||
|  |   OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty | ||||||
|  |   ); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   Variable property set. |   Variable property set. | ||||||
|  |  | ||||||
| @@ -778,6 +803,15 @@ VarCheckVariablePropertyGet ( | |||||||
|   OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty |   OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |   Initialize variable quota. | ||||||
|  |  | ||||||
|  | **/ | ||||||
|  | VOID | ||||||
|  | InitializeVariableQuota ( | ||||||
|  |   VOID | ||||||
|  |   ); | ||||||
|  |  | ||||||
| extern VARIABLE_MODULE_GLOBAL  *mVariableModuleGlobal; | extern VARIABLE_MODULE_GLOBAL  *mVariableModuleGlobal; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -286,6 +286,10 @@ OnReadyToBoot ( | |||||||
|   // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled. |   // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled. | ||||||
|   // |   // | ||||||
|   mEndOfDxe = TRUE; |   mEndOfDxe = TRUE; | ||||||
|  |   // | ||||||
|  |   // The initialization for variable quota. | ||||||
|  |   // | ||||||
|  |   InitializeVariableQuota (); | ||||||
|   ReclaimForOS (); |   ReclaimForOS (); | ||||||
|   if (FeaturePcdGet (PcdVariableCollectStatistics)) { |   if (FeaturePcdGet (PcdVariableCollectStatistics)) { | ||||||
|     gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid, gVariableInfo); |     gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid, gVariableInfo); | ||||||
| @@ -309,6 +313,10 @@ OnEndOfDxe ( | |||||||
|   ) |   ) | ||||||
| { | { | ||||||
|   mEndOfDxe = TRUE; |   mEndOfDxe = TRUE; | ||||||
|  |   // | ||||||
|  |   // The initialization for variable quota. | ||||||
|  |   // | ||||||
|  |   InitializeVariableQuota (); | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -132,6 +132,7 @@ | |||||||
|   gEfiSystemNvDataFvGuid                   ## CONSUMES               ## GUID |   gEfiSystemNvDataFvGuid                   ## CONSUMES               ## GUID | ||||||
|   gEfiHardwareErrorVariableGuid            ## SOMETIMES_CONSUMES     ## Variable:L"HwErrRec####" |   gEfiHardwareErrorVariableGuid            ## SOMETIMES_CONSUMES     ## Variable:L"HwErrRec####" | ||||||
|   gEdkiiFaultTolerantWriteGuid             ## SOMETIMES_CONSUMES     ## HOB |   gEdkiiFaultTolerantWriteGuid             ## SOMETIMES_CONSUMES     ## HOB | ||||||
|  |   gEdkiiVarErrorFlagGuid                   ## CONSUMES               ## GUID | ||||||
|  |  | ||||||
| [Pcd] | [Pcd] | ||||||
|   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize       ## CONSUMES |   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize       ## CONSUMES | ||||||
| @@ -141,6 +142,8 @@ | |||||||
|   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize     ## CONSUMES |   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize     ## CONSUMES | ||||||
|   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize                ## CONSUMES |   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize                ## CONSUMES | ||||||
|   gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize                 ## CONSUMES |   gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize                 ## CONSUMES | ||||||
|  |   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxUserNvVariableSpaceSize           ## CONSUMES | ||||||
|  |   gEfiMdeModulePkgTokenSpaceGuid.PcdBoottimeReservedNvVariableSpaceSize  ## CONSUMES | ||||||
|  |  | ||||||
| [FeaturePcd] | [FeaturePcd] | ||||||
|   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics        ## CONSUMES  # statistic the information of variable. |   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics        ## CONSUMES  # statistic the information of variable. | ||||||
|   | |||||||
| @@ -716,6 +716,10 @@ SmmVariableHandler ( | |||||||
|  |  | ||||||
|     case SMM_VARIABLE_FUNCTION_READY_TO_BOOT: |     case SMM_VARIABLE_FUNCTION_READY_TO_BOOT: | ||||||
|       mEndOfDxe = TRUE; |       mEndOfDxe = TRUE; | ||||||
|  |       // | ||||||
|  |       // The initialization for variable quota. | ||||||
|  |       // | ||||||
|  |       InitializeVariableQuota (); | ||||||
|       if (AtRuntime()) { |       if (AtRuntime()) { | ||||||
|         Status = EFI_UNSUPPORTED; |         Status = EFI_UNSUPPORTED; | ||||||
|         break; |         break; | ||||||
| @@ -846,6 +850,10 @@ SmmEndOfDxeCallback ( | |||||||
| { | { | ||||||
|   DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n")); |   DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n")); | ||||||
|   mEndOfDxe = TRUE; |   mEndOfDxe = TRUE; | ||||||
|  |   // | ||||||
|  |   // The initialization for variable quota. | ||||||
|  |   // | ||||||
|  |   InitializeVariableQuota (); | ||||||
|   return EFI_SUCCESS; |   return EFI_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -139,6 +139,7 @@ | |||||||
|   gEfiSystemNvDataFvGuid                   ## CONSUMES               ## GUID |   gEfiSystemNvDataFvGuid                   ## CONSUMES               ## GUID | ||||||
|   gEfiHardwareErrorVariableGuid            ## SOMETIMES_CONSUMES     ## Variable:L"HwErrRec####" |   gEfiHardwareErrorVariableGuid            ## SOMETIMES_CONSUMES     ## Variable:L"HwErrRec####" | ||||||
|   gEdkiiFaultTolerantWriteGuid             ## SOMETIMES_CONSUMES     ## HOB |   gEdkiiFaultTolerantWriteGuid             ## SOMETIMES_CONSUMES     ## HOB | ||||||
|  |   gEdkiiVarErrorFlagGuid                   ## CONSUMES               ## GUID | ||||||
|  |  | ||||||
| [Pcd] | [Pcd] | ||||||
|   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize       ## CONSUMES |   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize       ## CONSUMES | ||||||
| @@ -148,6 +149,8 @@ | |||||||
|   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize     ## CONSUMES |   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize     ## CONSUMES | ||||||
|   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize                ## CONSUMES |   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize                ## CONSUMES | ||||||
|   gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize                 ## CONSUMES |   gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize                 ## CONSUMES | ||||||
|  |   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxUserNvVariableSpaceSize           ## CONSUMES | ||||||
|  |   gEfiMdeModulePkgTokenSpaceGuid.PcdBoottimeReservedNvVariableSpaceSize  ## CONSUMES | ||||||
|  |  | ||||||
| [FeaturePcd] | [FeaturePcd] | ||||||
|   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics        ## CONSUMES  # statistic the information of variable. |   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics        ## CONSUMES  # statistic the information of variable. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user