diff options
Diffstat (limited to 'MdeModulePkg')
-rw-r--r-- | MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c | 172 |
1 files changed, 131 insertions, 41 deletions
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c index 019f0a806d..9f6a9acd50 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -574,7 +574,8 @@ EFI_STATUS Reclaim (
IN EFI_PHYSICAL_ADDRESS VariableBase,
OUT UINTN *LastVariableOffset,
- IN BOOLEAN IsVolatile
+ IN BOOLEAN IsVolatile,
+ IN VARIABLE_HEADER *UpdatingVariable
)
/*++
@@ -596,12 +597,18 @@ Returns: --*/
{
VARIABLE_HEADER *Variable;
+ VARIABLE_HEADER *AddedVariable;
VARIABLE_HEADER *NextVariable;
+ VARIABLE_HEADER *NextAddedVariable;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINT8 *ValidBuffer;
- UINTN ValidBufferSize;
+ UINTN MaximumBufferSize;
UINTN VariableSize;
+ UINTN NameSize;
UINT8 *CurrPtr;
+ VOID *Point0;
+ VOID *Point1;
+ BOOLEAN FoundAdded;
EFI_STATUS Status;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
@@ -609,39 +616,47 @@ Returns: //
// Start Pointers for the variable.
//
- Variable = GetStartPointer (VariableStoreHeader);
- ValidBufferSize = sizeof (VARIABLE_STORE_HEADER);
+ Variable = GetStartPointer (VariableStoreHeader);
+ MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
- if (Variable->State == VAR_ADDED) {
+ if (Variable->State == VAR_ADDED ||
+ Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
+ ) {
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
- ValidBufferSize += VariableSize;
+ MaximumBufferSize += VariableSize;
}
Variable = NextVariable;
}
- ValidBuffer = AllocatePool (ValidBufferSize);
+ //
+ // Reserve the 1 Bytes with Oxff to identify the
+ // end of the variable buffer.
+ //
+ MaximumBufferSize += 1;
+ ValidBuffer = AllocatePool (MaximumBufferSize);
if (ValidBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
- SetMem (ValidBuffer, ValidBufferSize, 0xff);
-
- CurrPtr = ValidBuffer;
+ SetMem (ValidBuffer, MaximumBufferSize, 0xff);
//
// Copy variable store header
//
- CopyMem (CurrPtr, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));
- CurrPtr = (UINT8 *) GetStartPointer ((VARIABLE_STORE_HEADER *) CurrPtr);
+ CopyMem (ValidBuffer, VariableStoreHeader, sizeof (VARIABLE_STORE_HEADER));
+ CurrPtr = (UINT8 *) GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer);
//
// Start Pointers for the variable.
//
- Variable = GetStartPointer (VariableStoreHeader);
+ //
+ // Reinstall all ADDED variables
+ //
+ Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
if (Variable->State == VAR_ADDED) {
@@ -652,14 +667,61 @@ Returns: Variable = NextVariable;
}
+ //
+ // Reinstall all in delete transition variables
+ //
+ Variable = GetStartPointer (VariableStoreHeader);
+ while (IsValidVariableHeader (Variable)) {
+ NextVariable = GetNextVariablePtr (Variable);
+ if (Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+
+ //
+ // Buffer has cached all ADDED variable.
+ // Per IN_DELETED variable, we have to guarantee that
+ // no ADDED one in previous buffer.
+ //
+
+ FoundAdded = FALSE;
+ AddedVariable = GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer);
+ while (IsValidVariableHeader (AddedVariable)) {
+ NextAddedVariable = GetNextVariablePtr (AddedVariable);
+ NameSize = NameSizeOfVariable (AddedVariable);
+ if (CompareGuid (&AddedVariable->VendorGuid, &Variable->VendorGuid) &&
+ NameSize == NameSizeOfVariable (Variable)
+ ) {
+ Point0 = (VOID *) GetVariableNamePtr (AddedVariable);
+ Point1 = (VOID *) GetVariableNamePtr (Variable);
+ if (!CompareMem (
+ Point0,
+ Point1,
+ NameSizeOfVariable (AddedVariable)
+ )
+ ) {
+ FoundAdded = TRUE;
+ break;
+ }
+ }
+ AddedVariable = NextAddedVariable;
+ }
+ if (!FoundAdded) {
+ VariableSize = (UINTN) NextVariable - (UINTN) Variable;
+ CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
+ if (Variable != UpdatingVariable) {
+ ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED;
+ }
+ CurrPtr += VariableSize;
+ }
+ }
+
+ Variable = NextVariable;
+ }
if (IsVolatile) {
//
// If volatile variable store, just copy valid buffer
//
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
- CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, ValidBufferSize);
- *LastVariableOffset = ValidBufferSize;
+ CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - (UINT8 *) ValidBuffer));
Status = EFI_SUCCESS;
} else {
//
@@ -668,19 +730,17 @@ Returns: Status = FtwVariableSpace (
VariableBase,
ValidBuffer,
- ValidBufferSize
+ (UINTN) (CurrPtr - (UINT8 *) ValidBuffer)
);
- if (!EFI_ERROR (Status)) {
- *LastVariableOffset = ValidBufferSize;
- }
}
-
- FreePool (ValidBuffer);
-
- if (EFI_ERROR (Status)) {
+ if (!EFI_ERROR (Status)) {
+ *LastVariableOffset = (UINTN) (CurrPtr - (UINT8 *) ValidBuffer);
+ } else {
*LastVariableOffset = 0;
}
+ FreePool (ValidBuffer);
+
return Status;
}
@@ -838,10 +898,12 @@ Returns: --*/
{
- VARIABLE_HEADER *Variable[2];
- VARIABLE_STORE_HEADER *VariableStoreHeader[2];
- UINTN Index;
- VOID *Point;
+ VARIABLE_HEADER *Variable[2];
+ VARIABLE_HEADER *InDeletedVariable;
+ VARIABLE_STORE_HEADER *VariableStoreHeader[2];
+ UINTN InDeletedStorageIndex;
+ UINTN Index;
+ VOID *Point;
//
// 0: Volatile, 1: Non-Volatile
@@ -861,29 +923,47 @@ Returns: if (VariableName[0] != 0 && VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
+
//
// Find the variable by walk through volatile and then non-volatile variable store
//
+ InDeletedVariable = NULL;
+ InDeletedStorageIndex = 0;
for (Index = 0; Index < 2; Index++) {
- PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[Index]);
- PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);
-
while (IsValidVariableHeader (Variable[Index]) && (Variable[Index] <= GetEndPointer (VariableStoreHeader[Index]))) {
- if (Variable[Index]->State == VAR_ADDED) {
+ if (Variable[Index]->State == VAR_ADDED ||
+ Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
+ ) {
if (!EfiAtRuntime () || (Variable[Index]->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)) {
if (VariableName[0] == 0) {
- PtrTrack->CurrPtr = Variable[Index];
- PtrTrack->Volatile = (BOOLEAN)(Index == 0);
- return EFI_SUCCESS;
+ if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+ InDeletedVariable = Variable[Index];
+ InDeletedStorageIndex = Index;
+ } else {
+ PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[Index]);
+ PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);
+ PtrTrack->CurrPtr = Variable[Index];
+ PtrTrack->Volatile = (BOOLEAN)(Index == 0);
+
+ return EFI_SUCCESS;
+ }
} else {
if (CompareGuid (VendorGuid, &Variable[Index]->VendorGuid)) {
Point = (VOID *) GetVariableNamePtr (Variable[Index]);
ASSERT (NameSizeOfVariable (Variable[Index]) != 0);
if (!CompareMem (VariableName, Point, NameSizeOfVariable (Variable[Index]))) {
- PtrTrack->CurrPtr = Variable[Index];
- PtrTrack->Volatile = (BOOLEAN)(Index == 0);
- return EFI_SUCCESS;
+ if (Variable[Index]->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+ InDeletedVariable = Variable[Index];
+ InDeletedStorageIndex = Index;
+ } else {
+ PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[Index]);
+ PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[Index]);
+ PtrTrack->CurrPtr = Variable[Index];
+ PtrTrack->Volatile = (BOOLEAN)(Index == 0);
+
+ return EFI_SUCCESS;
+ }
}
}
}
@@ -892,6 +972,13 @@ Returns: Variable[Index] = GetNextVariablePtr (Variable[Index]);
}
+ if (InDeletedVariable != NULL) {
+ PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader[InDeletedStorageIndex]);
+ PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader[InDeletedStorageIndex]);
+ PtrTrack->CurrPtr = InDeletedVariable;
+ PtrTrack->Volatile = (BOOLEAN)(InDeletedStorageIndex == 0);
+ return EFI_SUCCESS;
+ }
}
PtrTrack->CurrPtr = NULL;
return EFI_NOT_FOUND;
@@ -1279,6 +1366,7 @@ RuntimeServiceSetVariable ( goto Done;
} else if ((Variable.CurrPtr->State == VAR_ADDED) ||
(Variable.CurrPtr->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION))) {
+
//
// Mark the old variable as in delete transition
//
@@ -1388,7 +1476,7 @@ RuntimeServiceSetVariable ( //
// Perform garbage collection & reclaim operation
//
- Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, NonVolatileOffset, FALSE);
+ Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, NonVolatileOffset, FALSE, Variable.CurrPtr);
if (EFI_ERROR (Status)) {
goto Done;
}
@@ -1492,7 +1580,7 @@ RuntimeServiceSetVariable ( //
// Perform garbage collection & reclaim operation
//
- Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, VolatileOffset, TRUE);
+ Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase, VolatileOffset, TRUE, Variable.CurrPtr);
if (EFI_ERROR (Status)) {
goto Done;
}
@@ -1723,7 +1811,8 @@ ReclaimForOS( Status = Reclaim (
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
- FALSE
+ FALSE,
+ NULL
);
ASSERT_EFI_ERROR (Status);
}
@@ -1912,7 +2001,8 @@ Returns: Status = Reclaim (
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
- FALSE
+ FALSE,
+ NULL
);
if (EFI_ERROR (Status)) {
|