From 128ef095b06aa16dfb2aa990af41de85eb6f6ea7 Mon Sep 17 00:00:00 2001 From: Star Zeng Date: Tue, 12 Nov 2013 13:31:43 +0000 Subject: [PATCH] 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 Reviewed-by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14832 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/Variable/RuntimeDxe/Reclaim.c | 24 +-- .../Universal/Variable/RuntimeDxe/Variable.c | 109 ++++++++------ .../Universal/Variable/RuntimeDxe/Variable.h | 6 +- .../RuntimeDxe/Reclaim.c | 24 +-- .../RuntimeDxe/Variable.c | 139 ++++++++++-------- .../RuntimeDxe/Variable.h | 6 +- 6 files changed, 152 insertions(+), 156 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c index 11bf1a02b6..1732a0cd69 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c @@ -3,7 +3,7 @@ Handles non-volatile variable store garbage collection, using FTW (Fault Tolerant Write) protocol. -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
This program and the accompanying materials 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 @@ -99,8 +99,7 @@ GetLbaAndOffsetByAddress ( VariableBase. Fault Tolerant Write protocol is used for writing. @param VariableBase Base address of variable to write - @param Buffer Point to the data buffer. - @param BufferSize The number of bytes of the data Buffer. + @param VariableBuffer Point to the variable data buffer. @retval EFI_SUCCESS The function completed successfully. @retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol. @@ -110,15 +109,13 @@ GetLbaAndOffsetByAddress ( EFI_STATUS FtwVariableSpace ( IN EFI_PHYSICAL_ADDRESS VariableBase, - IN UINT8 *Buffer, - IN UINTN BufferSize + IN VARIABLE_STORE_HEADER *VariableBuffer ) { EFI_STATUS Status; EFI_HANDLE FvbHandle; EFI_LBA VarLba; UINTN VarOffset; - UINT8 *FtwBuffer; UINTN FtwBufferSize; EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol; @@ -143,17 +140,9 @@ FtwVariableSpace ( if (EFI_ERROR (Status)) { 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); - CopyMem (FtwBuffer, Buffer, BufferSize); + FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size; + ASSERT (FtwBufferSize == VariableBuffer->Size); // // FTW write record. @@ -165,9 +154,8 @@ FtwVariableSpace ( FtwBufferSize, // NumBytes NULL, // PrivateData NULL FvbHandle, // Fvb Handle - FtwBuffer // write buffer + (VOID *) VariableBuffer // write buffer ); - FreePool (FtwBuffer); return Status; } diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c index 645818dfdf..c66eb87506 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -615,40 +615,49 @@ Reclaim ( CommonVariableTotalSize = 0; HwErrVariableTotalSize = 0; - // - // Start Pointers for the variable. - // - Variable = GetStartPointer (VariableStoreHeader); - MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER); + if (IsVolatile) { + // + // Start Pointers for the variable. + // + Variable = GetStartPointer (VariableStoreHeader); + MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER); - while (IsValidVariableHeader (Variable)) { - NextVariable = GetNextVariablePtr (Variable); - if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) && - Variable != UpdatingVariable && - Variable != UpdatingInDeletedTransition - ) { - VariableSize = (UINTN) NextVariable - (UINTN) Variable; - MaximumBufferSize += VariableSize; + while (IsValidVariableHeader (Variable)) { + NextVariable = GetNextVariablePtr (Variable); + if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) && + Variable != UpdatingVariable && + Variable != UpdatingInDeletedTransition + ) { + VariableSize = (UINTN) NextVariable - (UINTN) Variable; + MaximumBufferSize += VariableSize; + } + + Variable = NextVariable; } - Variable = NextVariable; - } + if (NewVariable != NULL) { + // + // Add the new variable size. + // + MaximumBufferSize += NewVariableSize; + } - if (NewVariable != NULL) { // - // Add the new variable size. + // Reserve the 1 Bytes with Oxff to identify the + // end of the variable buffer. // - MaximumBufferSize += NewVariableSize; - } - - // - // 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; + MaximumBufferSize += 1; + ValidBuffer = AllocatePool (MaximumBufferSize); + if (ValidBuffer == NULL) { + 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); @@ -770,6 +779,7 @@ Reclaim ( // SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff); CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer)); + *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); Status = EFI_SUCCESS; } else { // @@ -777,34 +787,37 @@ Reclaim ( // Status = FtwVariableSpace ( VariableBase, - ValidBuffer, - (UINTN) (CurrPtr - ValidBuffer) + (VARIABLE_STORE_HEADER *) ValidBuffer ); - CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, VariableStoreHeader->Size); - } - if (!EFI_ERROR (Status)) { - *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); - if (!IsVolatile) { + if (!EFI_ERROR (Status)) { + *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize; mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize; - } - } else { - NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); - while (IsValidVariableHeader (NextVariable)) { - VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); - if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { - mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); - } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { - mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); - } + } else { + NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); + while (IsValidVariableHeader (NextVariable)) { + VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); + if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { + mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); + } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { + mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); + } - NextVariable = GetNextVariablePtr (NextVariable); + NextVariable = GetNextVariablePtr (NextVariable); + } + *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase; } - *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase; } Done: - FreePool (ValidBuffer); + 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); + } return Status; } diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h index a10ad8755a..9c8626cdc4 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h @@ -133,8 +133,7 @@ FlushHobVariableToFlash ( VariableBase. Fault Tolerant Write protocol is used for writing. @param VariableBase Base address of the variable to write. - @param Buffer Point to the data buffer. - @param BufferSize The number of bytes of the data Buffer. + @param VariableBuffer Point to the variable data buffer. @retval EFI_SUCCESS The function completed successfully. @retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol. @@ -144,8 +143,7 @@ FlushHobVariableToFlash ( EFI_STATUS FtwVariableSpace ( IN EFI_PHYSICAL_ADDRESS VariableBase, - IN UINT8 *Buffer, - IN UINTN BufferSize + IN VARIABLE_STORE_HEADER *VariableBuffer ); diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c index 4f7a41cd09..b20facd9d8 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c @@ -2,7 +2,7 @@ Handles non-volatile variable store garbage collection, using FTW (Fault Tolerant Write) protocol. -Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
This program and the accompanying materials 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 @@ -98,8 +98,7 @@ GetLbaAndOffsetByAddress ( VariableBase. Fault Tolerant Write protocol is used for writing. @param VariableBase Base address of variable to write - @param Buffer Point to the data buffer. - @param BufferSize The number of bytes of the data Buffer. + @param VariableBuffer Point to the variable data buffer. @retval EFI_SUCCESS The function completed successfully. @retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol. @@ -109,15 +108,13 @@ GetLbaAndOffsetByAddress ( EFI_STATUS FtwVariableSpace ( IN EFI_PHYSICAL_ADDRESS VariableBase, - IN UINT8 *Buffer, - IN UINTN BufferSize + IN VARIABLE_STORE_HEADER *VariableBuffer ) { EFI_STATUS Status; EFI_HANDLE FvbHandle; EFI_LBA VarLba; UINTN VarOffset; - UINT8 *FtwBuffer; UINTN FtwBufferSize; EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol; @@ -142,17 +139,9 @@ FtwVariableSpace ( if (EFI_ERROR (Status)) { 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); - CopyMem (FtwBuffer, Buffer, BufferSize); + FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size; + ASSERT (FtwBufferSize == VariableBuffer->Size); // // FTW write record. @@ -164,9 +153,8 @@ FtwVariableSpace ( FtwBufferSize, // NumBytes NULL, // PrivateData NULL FvbHandle, // Fvb Handle - FtwBuffer // write buffer + (VOID *) VariableBuffer // write buffer ); - FreePool (FtwBuffer); return Status; } diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c index 534f6a8c8f..adcf25c313 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c @@ -701,6 +701,7 @@ PubKeyStoreFilter ( *NewPubKeyIndex = AllocateZeroPool ((PubKeyNumber + 1) * sizeof (UINT32)); if (*NewPubKeyIndex == NULL) { FreePool (*NewPubKeyStore); + *NewPubKeyStore = NULL; return EFI_OUT_OF_RESOURCES; } @@ -790,41 +791,50 @@ Reclaim ( NewPubKeyStore = NULL; NewPubKeySize = 0; PubKeyHeader = NULL; - - // - // Start Pointers for the variable. - // - Variable = GetStartPointer (VariableStoreHeader); - MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER); - while (IsValidVariableHeader (Variable)) { - NextVariable = GetNextVariablePtr (Variable); - if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) && - Variable != UpdatingVariable && - Variable != UpdatingInDeletedTransition - ) { - VariableSize = (UINTN) NextVariable - (UINTN) Variable; - MaximumBufferSize += VariableSize; + if (IsVolatile) { + // + // Start Pointers for the variable. + // + Variable = GetStartPointer (VariableStoreHeader); + MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER); + + while (IsValidVariableHeader (Variable)) { + NextVariable = GetNextVariablePtr (Variable); + if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) && + Variable != UpdatingVariable && + Variable != UpdatingInDeletedTransition + ) { + VariableSize = (UINTN) NextVariable - (UINTN) Variable; + MaximumBufferSize += VariableSize; + } + + Variable = NextVariable; } - Variable = NextVariable; - } + if (NewVariable != NULL) { + // + // Add the new variable size. + // + MaximumBufferSize += NewVariableSize; + } - if (NewVariable != NULL) { // - // Add the new variable size. + // Reserve the 1 Bytes with Oxff to identify the + // end of the variable buffer. // - MaximumBufferSize += NewVariableSize; - } - - // - // 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; + MaximumBufferSize += 1; + ValidBuffer = AllocatePool (MaximumBufferSize); + if (ValidBuffer == NULL) { + 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); @@ -848,14 +858,13 @@ Reclaim ( &NewPubKeySize ); if (EFI_ERROR (Status)) { - FreePool (ValidBuffer); - return Status; + goto Done; } // // Refresh the PubKeyIndex for all valid variables (ADDED and IN_DELETED_TRANSITION). // - Variable = GetStartPointer (mNvVariableCache); + Variable = GetStartPointer (VariableStoreHeader); while (IsValidVariableHeader (Variable)) { NextVariable = GetNextVariablePtr (Variable); if (Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { @@ -887,10 +896,8 @@ Reclaim ( // ASSERT (PubKeyHeader != NULL); if (PubKeyHeader == NULL) { - FreePool (ValidBuffer); - FreePool (NewPubKeyIndex); - FreePool (NewPubKeyStore); - return EFI_DEVICE_ERROR; + Status = EFI_DEVICE_ERROR; + goto Done; } CopyMem (CurrPtr, (UINT8*) PubKeyHeader, sizeof (VARIABLE_HEADER)); Variable = (VARIABLE_HEADER*) CurrPtr; @@ -1012,6 +1019,7 @@ Reclaim ( // SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff); CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer)); + *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); Status = EFI_SUCCESS; } else { // @@ -1019,42 +1027,45 @@ Reclaim ( // Status = FtwVariableSpace ( VariableBase, - ValidBuffer, - (UINTN) (CurrPtr - ValidBuffer) + (VARIABLE_STORE_HEADER *) ValidBuffer ); - CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, VariableStoreHeader->Size); - } - if (!EFI_ERROR (Status)) { - *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); - if (!IsVolatile) { + if (!EFI_ERROR (Status)) { + *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize; mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize; - } - } else { - NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); - while (IsValidVariableHeader (NextVariable)) { - VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); - if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { - mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); - } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { - mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); + } else { + NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); + while (IsValidVariableHeader (NextVariable)) { + VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); + if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { + mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); + } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { + mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); + } + + NextVariable = GetNextVariablePtr (NextVariable); } - - NextVariable = GetNextVariablePtr (NextVariable); + *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase; } - *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase; - } - - if (NewPubKeyStore != NULL) { - FreePool (NewPubKeyStore); - } - - if (NewPubKeyIndex != NULL) { - FreePool (NewPubKeyIndex); } Done: - FreePool (ValidBuffer); + 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) { + FreePool (NewPubKeyStore); + } + + if (NewPubKeyIndex != NULL) { + FreePool (NewPubKeyIndex); + } + } return Status; } diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h index 1cea45e507..b4512d2cca 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h @@ -143,8 +143,7 @@ FlushHobVariableToFlash ( VariableBase. Fault Tolerant Write protocol is used for writing. @param VariableBase Base address of the variable to write. - @param Buffer Point to the data buffer. - @param BufferSize The number of bytes of the data Buffer. + @param VariableBuffer Point to the variable data buffer. @retval EFI_SUCCESS The function completed successfully. @retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol. @@ -154,8 +153,7 @@ FlushHobVariableToFlash ( EFI_STATUS FtwVariableSpace ( IN EFI_PHYSICAL_ADDRESS VariableBase, - IN UINT8 *Buffer, - IN UINTN BufferSize + IN VARIABLE_STORE_HEADER *VariableBuffer ); /**