@param[out] LastVariableOffset Offset of last variable.\r
@param[in] IsVolatile The variable store is volatile or not;\r
if it is non-volatile, need FTW.\r
- @param[in] UpdatingVariable Pointer to updating variable.\r
+ @param[in, out] UpdatingPtrTrack Pointer to updating variable pointer track structure.\r
@param[in] ReclaimPubKeyStore Reclaim for public key database or not.\r
@param[in] ReclaimAnyway If TRUE, do reclaim anyway.\r
\r
IN EFI_PHYSICAL_ADDRESS VariableBase,\r
OUT UINTN *LastVariableOffset,\r
IN BOOLEAN IsVolatile,\r
- IN VARIABLE_HEADER *UpdatingVariable,\r
+ IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack,\r
IN BOOLEAN ReclaimPubKeyStore,\r
IN BOOLEAN ReclaimAnyway\r
)\r
UINT32 NewPubKeySize;\r
VARIABLE_HEADER *PubKeyHeader;\r
BOOLEAN NeedDoReclaim;\r
+ VARIABLE_HEADER *UpdatingVariable;\r
+\r
+ UpdatingVariable = NULL;\r
+ if (UpdatingPtrTrack != NULL) {\r
+ UpdatingVariable = UpdatingPtrTrack->CurrPtr;\r
+ }\r
\r
NeedDoReclaim = FALSE;\r
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);\r
if (UpdatingVariable != NULL) {\r
VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - (UINTN)UpdatingVariable;\r
CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize);\r
+ UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER *)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer)));\r
+ UpdatingPtrTrack->InDeletedTransitionPtr = NULL;\r
CurrPtr += VariableSize;\r
if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
HwErrVariableTotalSize += VariableSize;\r
) {\r
Point0 = (VOID *) GetVariableNamePtr (AddedVariable);\r
Point1 = (VOID *) GetVariableNamePtr (Variable);\r
- if (CompareMem (Point0, Point1, NameSizeOfVariable (AddedVariable)) == 0) {\r
+ if (CompareMem (Point0, Point1, NameSize) == 0) {\r
FoundAdded = TRUE;\r
break;\r
}\r
VARIABLE_HEADER *InDeletedVariable;\r
VOID *Point;\r
\r
+ PtrTrack->InDeletedTransitionPtr = NULL;\r
+\r
//\r
// Find the variable by walk through HOB, volatile and non-volatile variable store.\r
//\r
if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
InDeletedVariable = PtrTrack->CurrPtr;\r
} else {\r
+ PtrTrack->InDeletedTransitionPtr = InDeletedVariable;\r
return EFI_SUCCESS;\r
}\r
} else {\r
if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
InDeletedVariable = PtrTrack->CurrPtr;\r
} else {\r
+ PtrTrack->InDeletedTransitionPtr = InDeletedVariable;\r
return EFI_SUCCESS;\r
}\r
}\r
@param[in] Attributes Attributes of the variable.\r
@param[in] KeyIndex Index of associated public key.\r
@param[in] MonotonicCount Value of associated monotonic count.\r
- @param[in] CacheVariable The variable information which is used to keep track of variable usage.\r
+ @param[in, out] CacheVariable The variable information which is used to keep track of variable usage.\r
@param[in] TimeStamp Value of associated TimeStamp.\r
\r
@retval EFI_SUCCESS The update operation is success.\r
IN UINT32 Attributes OPTIONAL,\r
IN UINT32 KeyIndex OPTIONAL,\r
IN UINT64 MonotonicCount OPTIONAL,\r
- IN VARIABLE_POINTER_TRACK *CacheVariable,\r
+ IN OUT VARIABLE_POINTER_TRACK *CacheVariable,\r
IN EFI_TIME *TimeStamp OPTIONAL\r
)\r
{\r
BOOLEAN Volatile;\r
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;\r
UINT8 State;\r
- BOOLEAN Reclaimed;\r
VARIABLE_POINTER_TRACK *Variable;\r
VARIABLE_POINTER_TRACK NvVariable;\r
VARIABLE_STORE_HEADER *VariableStoreHeader;\r
Variable->StartPtr = GetStartPointer (VariableStoreHeader);\r
Variable->EndPtr = GetEndPointer (VariableStoreHeader);\r
Variable->CurrPtr = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->CurrPtr - (UINTN)CacheVariable->StartPtr));\r
+ if (CacheVariable->InDeletedTransitionPtr != NULL) {\r
+ Variable->InDeletedTransitionPtr = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->InDeletedTransitionPtr - (UINTN)CacheVariable->StartPtr));\r
+ } else {\r
+ Variable->InDeletedTransitionPtr = NULL;\r
+ }\r
Variable->Volatile = FALSE;\r
}\r
\r
Fvb = mVariableModuleGlobal->FvbInstance;\r
- Reclaimed = FALSE;\r
\r
//\r
// Tricky part: Use scratch data area at the end of volatile variable store\r
// not delete the variable.\r
//\r
if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0))|| ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == 0)) {\r
+ if (Variable->InDeletedTransitionPtr != NULL) {\r
+ //\r
+ // Both ADDED and IN_DELETED_TRANSITION variable are present,\r
+ // set IN_DELETED_TRANSITION one to DELETED state first.\r
+ //\r
+ State = Variable->InDeletedTransitionPtr->State;\r
+ State &= VAR_DELETED;\r
+ Status = UpdateVariableStore (\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ Variable->Volatile,\r
+ FALSE,\r
+ Fvb,\r
+ (UINTN) &Variable->InDeletedTransitionPtr->State,\r
+ sizeof (UINT8),\r
+ &State\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ if (!Variable->Volatile) {\r
+ CacheVariable->InDeletedTransitionPtr->State = State;\r
+ }\r
+ } else {\r
+ goto Done;\r
+ }\r
+ }\r
+\r
State = Variable->CurrPtr->State;\r
State &= VAR_DELETED;\r
\r
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,\r
&mVariableModuleGlobal->NonVolatileLastVariableOffset,\r
FALSE,\r
- Variable->CurrPtr,\r
+ Variable,\r
FALSE,\r
FALSE\r
);\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
- Reclaimed = TRUE;\r
+ if (Variable->CurrPtr != NULL) {\r
+ CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));\r
+ CacheVariable->InDeletedTransitionPtr = NULL;\r
+ }\r
}\r
//\r
// Four steps\r
mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,\r
&mVariableModuleGlobal->VolatileLastVariableOffset,\r
TRUE,\r
- Variable->CurrPtr,\r
+ Variable,\r
FALSE,\r
FALSE\r
);\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
- Reclaimed = TRUE;\r
+ if (Variable->CurrPtr != NULL) {\r
+ CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));\r
+ CacheVariable->InDeletedTransitionPtr = NULL;\r
+ }\r
}\r
\r
NextVariable->State = VAR_ADDED;\r
//\r
// Mark the old variable as deleted.\r
//\r
- if (!Reclaimed && !EFI_ERROR (Status) && Variable->CurrPtr != NULL) {\r
+ if (!EFI_ERROR (Status) && Variable->CurrPtr != NULL) {\r
+ if (Variable->InDeletedTransitionPtr != NULL) {\r
+ //\r
+ // Both ADDED and IN_DELETED_TRANSITION old variable are present,\r
+ // set IN_DELETED_TRANSITION one to DELETED state first.\r
+ //\r
+ State = Variable->InDeletedTransitionPtr->State;\r
+ State &= VAR_DELETED;\r
+ Status = UpdateVariableStore (\r
+ &mVariableModuleGlobal->VariableGlobal,\r
+ Variable->Volatile,\r
+ FALSE,\r
+ Fvb,\r
+ (UINTN) &Variable->InDeletedTransitionPtr->State,\r
+ sizeof (UINT8),\r
+ &State\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ if (!Variable->Volatile) {\r
+ CacheVariable->InDeletedTransitionPtr->State = State;\r
+ }\r
+ } else {\r
+ goto Done;\r
+ }\r
+ }\r
+\r
State = Variable->CurrPtr->State;\r
State &= VAR_DELETED;\r
\r
VARIABLE_STORE_TYPE Type;\r
VARIABLE_POINTER_TRACK Variable;\r
VARIABLE_POINTER_TRACK VariableInHob;\r
+ VARIABLE_POINTER_TRACK VariablePtrTrack;\r
UINTN VarNameSize;\r
EFI_STATUS Status;\r
VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax];\r
//\r
// Variable is found\r
//\r
- if (Variable.CurrPtr->State == VAR_ADDED) {\r
- if ((AtRuntime () && ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) == 0) {\r
+ if (Variable.CurrPtr->State == VAR_ADDED || Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
+ if (!AtRuntime () || ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {\r
+ if (Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {\r
+ //\r
+ // If it is a IN_DELETED_TRANSITION variable,\r
+ // and there is also a same ADDED one at the same time,\r
+ // don't return it.\r
+ //\r
+ VariablePtrTrack.StartPtr = Variable.StartPtr;\r
+ VariablePtrTrack.EndPtr = Variable.EndPtr;\r
+ Status = FindVariableEx (\r
+ GetVariableNamePtr (Variable.CurrPtr),\r
+ &Variable.CurrPtr->VendorGuid,\r
+ FALSE,\r
+ &VariablePtrTrack\r
+ );\r
+ if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State == VAR_ADDED) {\r
+ Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
+ continue;\r
+ }\r
+ }\r
\r
//\r
// Don't return NV variable when HOB overrides it\r