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