MdeModulePkg and SecurityPkg Variable: Optimize the code to reduce some SMRAM consumption during variable reclaiming.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14832 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Star Zeng 2013-11-12 13:31:43 +00:00 committed by lzeng14
parent 414ec46146
commit 128ef095b0
6 changed files with 152 additions and 156 deletions

View File

@ -3,7 +3,7 @@
Handles non-volatile variable store garbage collection, using FTW Handles non-volatile variable store garbage collection, using FTW
(Fault Tolerant Write) protocol. (Fault Tolerant Write) protocol.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -99,8 +99,7 @@ GetLbaAndOffsetByAddress (
VariableBase. Fault Tolerant Write protocol is used for writing. VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of variable to write @param VariableBase Base address of variable to write
@param Buffer Point to the data buffer. @param VariableBuffer Point to the variable data buffer.
@param BufferSize The number of bytes of the data Buffer.
@retval EFI_SUCCESS The function completed successfully. @retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol. @retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@ -110,15 +109,13 @@ GetLbaAndOffsetByAddress (
EFI_STATUS EFI_STATUS
FtwVariableSpace ( FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase, IN EFI_PHYSICAL_ADDRESS VariableBase,
IN UINT8 *Buffer, IN VARIABLE_STORE_HEADER *VariableBuffer
IN UINTN BufferSize
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_HANDLE FvbHandle; EFI_HANDLE FvbHandle;
EFI_LBA VarLba; EFI_LBA VarLba;
UINTN VarOffset; UINTN VarOffset;
UINT8 *FtwBuffer;
UINTN FtwBufferSize; UINTN FtwBufferSize;
EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol; EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
@ -143,17 +140,9 @@ FtwVariableSpace (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_ABORTED; return EFI_ABORTED;
} }
//
// Prepare for the variable data.
//
FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
FtwBuffer = AllocatePool (FtwBufferSize);
if (FtwBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff); FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
CopyMem (FtwBuffer, Buffer, BufferSize); ASSERT (FtwBufferSize == VariableBuffer->Size);
// //
// FTW write record. // FTW write record.
@ -165,9 +154,8 @@ FtwVariableSpace (
FtwBufferSize, // NumBytes FtwBufferSize, // NumBytes
NULL, // PrivateData NULL NULL, // PrivateData NULL
FvbHandle, // Fvb Handle FvbHandle, // Fvb Handle
FtwBuffer // write buffer (VOID *) VariableBuffer // write buffer
); );
FreePool (FtwBuffer);
return Status; return Status;
} }

View File

@ -615,6 +615,7 @@ Reclaim (
CommonVariableTotalSize = 0; CommonVariableTotalSize = 0;
HwErrVariableTotalSize = 0; HwErrVariableTotalSize = 0;
if (IsVolatile) {
// //
// Start Pointers for the variable. // Start Pointers for the variable.
// //
@ -650,6 +651,14 @@ Reclaim (
if (ValidBuffer == NULL) { if (ValidBuffer == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
} else {
//
// For NV variable reclaim, don't allocate pool here and just use mNvVariableCache
// as the buffer to reduce SMRAM consumption for SMM variable driver.
//
MaximumBufferSize = mNvVariableCache->Size;
ValidBuffer = (UINT8 *) mNvVariableCache;
}
SetMem (ValidBuffer, MaximumBufferSize, 0xff); SetMem (ValidBuffer, MaximumBufferSize, 0xff);
@ -770,6 +779,7 @@ Reclaim (
// //
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff); SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer)); CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer));
*LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
} else { } else {
// //
@ -777,24 +787,19 @@ Reclaim (
// //
Status = FtwVariableSpace ( Status = FtwVariableSpace (
VariableBase, VariableBase,
ValidBuffer, (VARIABLE_STORE_HEADER *) ValidBuffer
(UINTN) (CurrPtr - ValidBuffer)
); );
CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, VariableStoreHeader->Size);
}
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
*LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
if (!IsVolatile) {
mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize; mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize;
mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize; mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize;
}
} else { } else {
NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);
while (IsValidVariableHeader (NextVariable)) { while (IsValidVariableHeader (NextVariable)) {
VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);
if ((!IsVolatile) && ((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 += HEADER_ALIGN (VariableSize);
} else if ((!IsVolatile) && ((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 += HEADER_ALIGN (VariableSize);
} }
@ -802,9 +807,17 @@ Reclaim (
} }
*LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase; *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase;
} }
}
Done: Done:
if (IsVolatile) {
FreePool (ValidBuffer); FreePool (ValidBuffer);
} else {
//
// For NV variable reclaim, we use mNvVariableCache as the buffer, so copy the data back.
//
CopyMem (mNvVariableCache, (UINT8 *)(UINTN)VariableBase, VariableStoreHeader->Size);
}
return Status; return Status;
} }

View File

@ -133,8 +133,7 @@ FlushHobVariableToFlash (
VariableBase. Fault Tolerant Write protocol is used for writing. VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of the variable to write. @param VariableBase Base address of the variable to write.
@param Buffer Point to the data buffer. @param VariableBuffer Point to the variable data buffer.
@param BufferSize The number of bytes of the data Buffer.
@retval EFI_SUCCESS The function completed successfully. @retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol. @retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@ -144,8 +143,7 @@ FlushHobVariableToFlash (
EFI_STATUS EFI_STATUS
FtwVariableSpace ( FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase, IN EFI_PHYSICAL_ADDRESS VariableBase,
IN UINT8 *Buffer, IN VARIABLE_STORE_HEADER *VariableBuffer
IN UINTN BufferSize
); );

View File

@ -2,7 +2,7 @@
Handles non-volatile variable store garbage collection, using FTW Handles non-volatile variable store garbage collection, using FTW
(Fault Tolerant Write) protocol. (Fault Tolerant Write) protocol.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -98,8 +98,7 @@ GetLbaAndOffsetByAddress (
VariableBase. Fault Tolerant Write protocol is used for writing. VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of variable to write @param VariableBase Base address of variable to write
@param Buffer Point to the data buffer. @param VariableBuffer Point to the variable data buffer.
@param BufferSize The number of bytes of the data Buffer.
@retval EFI_SUCCESS The function completed successfully. @retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol. @retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@ -109,15 +108,13 @@ GetLbaAndOffsetByAddress (
EFI_STATUS EFI_STATUS
FtwVariableSpace ( FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase, IN EFI_PHYSICAL_ADDRESS VariableBase,
IN UINT8 *Buffer, IN VARIABLE_STORE_HEADER *VariableBuffer
IN UINTN BufferSize
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_HANDLE FvbHandle; EFI_HANDLE FvbHandle;
EFI_LBA VarLba; EFI_LBA VarLba;
UINTN VarOffset; UINTN VarOffset;
UINT8 *FtwBuffer;
UINTN FtwBufferSize; UINTN FtwBufferSize;
EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol; EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
@ -142,17 +139,9 @@ FtwVariableSpace (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_ABORTED; return EFI_ABORTED;
} }
//
// Prepare for the variable data.
//
FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
FtwBuffer = AllocatePool (FtwBufferSize);
if (FtwBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff); FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
CopyMem (FtwBuffer, Buffer, BufferSize); ASSERT (FtwBufferSize == VariableBuffer->Size);
// //
// FTW write record. // FTW write record.
@ -164,9 +153,8 @@ FtwVariableSpace (
FtwBufferSize, // NumBytes FtwBufferSize, // NumBytes
NULL, // PrivateData NULL NULL, // PrivateData NULL
FvbHandle, // Fvb Handle FvbHandle, // Fvb Handle
FtwBuffer // write buffer (VOID *) VariableBuffer // write buffer
); );
FreePool (FtwBuffer);
return Status; return Status;
} }

View File

@ -701,6 +701,7 @@ PubKeyStoreFilter (
*NewPubKeyIndex = AllocateZeroPool ((PubKeyNumber + 1) * sizeof (UINT32)); *NewPubKeyIndex = AllocateZeroPool ((PubKeyNumber + 1) * sizeof (UINT32));
if (*NewPubKeyIndex == NULL) { if (*NewPubKeyIndex == NULL) {
FreePool (*NewPubKeyStore); FreePool (*NewPubKeyStore);
*NewPubKeyStore = NULL;
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
@ -791,6 +792,7 @@ Reclaim (
NewPubKeySize = 0; NewPubKeySize = 0;
PubKeyHeader = NULL; PubKeyHeader = NULL;
if (IsVolatile) {
// //
// Start Pointers for the variable. // Start Pointers for the variable.
// //
@ -826,6 +828,14 @@ Reclaim (
if (ValidBuffer == NULL) { if (ValidBuffer == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
} else {
//
// For NV variable reclaim, don't allocate pool here and just use mNvVariableCache
// as the buffer to reduce SMRAM consumption for SMM variable driver.
//
MaximumBufferSize = mNvVariableCache->Size;
ValidBuffer = (UINT8 *) mNvVariableCache;
}
SetMem (ValidBuffer, MaximumBufferSize, 0xff); SetMem (ValidBuffer, MaximumBufferSize, 0xff);
@ -848,14 +858,13 @@ Reclaim (
&NewPubKeySize &NewPubKeySize
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
FreePool (ValidBuffer); goto Done;
return Status;
} }
// //
// Refresh the PubKeyIndex for all valid variables (ADDED and IN_DELETED_TRANSITION). // Refresh the PubKeyIndex for all valid variables (ADDED and IN_DELETED_TRANSITION).
// //
Variable = GetStartPointer (mNvVariableCache); Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) { while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable); NextVariable = GetNextVariablePtr (Variable);
if (Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { if (Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
@ -887,10 +896,8 @@ Reclaim (
// //
ASSERT (PubKeyHeader != NULL); ASSERT (PubKeyHeader != NULL);
if (PubKeyHeader == NULL) { if (PubKeyHeader == NULL) {
FreePool (ValidBuffer); Status = EFI_DEVICE_ERROR;
FreePool (NewPubKeyIndex); goto Done;
FreePool (NewPubKeyStore);
return EFI_DEVICE_ERROR;
} }
CopyMem (CurrPtr, (UINT8*) PubKeyHeader, sizeof (VARIABLE_HEADER)); CopyMem (CurrPtr, (UINT8*) PubKeyHeader, sizeof (VARIABLE_HEADER));
Variable = (VARIABLE_HEADER*) CurrPtr; Variable = (VARIABLE_HEADER*) CurrPtr;
@ -1012,6 +1019,7 @@ Reclaim (
// //
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff); SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer)); CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer));
*LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
} else { } else {
// //
@ -1019,24 +1027,19 @@ Reclaim (
// //
Status = FtwVariableSpace ( Status = FtwVariableSpace (
VariableBase, VariableBase,
ValidBuffer, (VARIABLE_STORE_HEADER *) ValidBuffer
(UINTN) (CurrPtr - ValidBuffer)
); );
CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, VariableStoreHeader->Size);
}
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
*LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
if (!IsVolatile) {
mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize; mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize;
mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize; mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize;
}
} else { } else {
NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);
while (IsValidVariableHeader (NextVariable)) { while (IsValidVariableHeader (NextVariable)) {
VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);
if ((!IsVolatile) && ((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 += HEADER_ALIGN (VariableSize);
} else if ((!IsVolatile) && ((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 += HEADER_ALIGN (VariableSize);
} }
@ -1044,6 +1047,16 @@ Reclaim (
} }
*LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase; *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase;
} }
}
Done:
if (IsVolatile) {
FreePool (ValidBuffer);
} else {
//
// For NV variable reclaim, we use mNvVariableCache as the buffer, so copy the data back.
//
CopyMem (mNvVariableCache, (UINT8 *)(UINTN)VariableBase, VariableStoreHeader->Size);
if (NewPubKeyStore != NULL) { if (NewPubKeyStore != NULL) {
FreePool (NewPubKeyStore); FreePool (NewPubKeyStore);
@ -1052,9 +1065,7 @@ Reclaim (
if (NewPubKeyIndex != NULL) { if (NewPubKeyIndex != NULL) {
FreePool (NewPubKeyIndex); FreePool (NewPubKeyIndex);
} }
}
Done:
FreePool (ValidBuffer);
return Status; return Status;
} }

View File

@ -143,8 +143,7 @@ FlushHobVariableToFlash (
VariableBase. Fault Tolerant Write protocol is used for writing. VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of the variable to write. @param VariableBase Base address of the variable to write.
@param Buffer Point to the data buffer. @param VariableBuffer Point to the variable data buffer.
@param BufferSize The number of bytes of the data Buffer.
@retval EFI_SUCCESS The function completed successfully. @retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol. @retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@ -154,8 +153,7 @@ FlushHobVariableToFlash (
EFI_STATUS EFI_STATUS
FtwVariableSpace ( FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase, IN EFI_PHYSICAL_ADDRESS VariableBase,
IN UINT8 *Buffer, IN VARIABLE_STORE_HEADER *VariableBuffer
IN UINTN BufferSize
); );
/** /**