On 1/31/2019 10:48 AM, Hao Wu wrote:
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1409
This commit will add the support to enlarge a LockBox when using the
LockBoxLib API UpdateLockBox().
Please note that the new support will ONLY work for LockBox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY set.
The functional uni-test for the commit is available at:
https://github.com/hwu25/edk2/tree/lockbox_unitest
Cc: Jian J Wang <jian.j.w...@intel.com>
Cc: Ray Ni <ray...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Hao Wu <hao.a...@intel.com>
---
MdeModulePkg/Include/Library/LockBoxLib.h | 7 ++-
MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.c | 7 ++-
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.c | 5 +-
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c | 5 +-
MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c | 57
++++++++++++++++++--
5 files changed, 72 insertions(+), 9 deletions(-)
diff --git a/MdeModulePkg/Include/Library/LockBoxLib.h
b/MdeModulePkg/Include/Library/LockBoxLib.h
index 5921731419..addce3bd4a 100644
--- a/MdeModulePkg/Include/Library/LockBoxLib.h
+++ b/MdeModulePkg/Include/Library/LockBoxLib.h
@@ -2,7 +2,7 @@
This library is only intended to be used by DXE modules that need save
confidential information to LockBox and get it by PEI modules in S3 phase.
-Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -85,7 +85,10 @@ SetLockBoxAttributes (
@retval RETURN_SUCCESS the information is saved successfully.
@retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or
Length is 0.
@retval RETURN_NOT_FOUND the requested GUID not found.
- @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold
new information.
+ @retval RETURN_BUFFER_TOO_SMALL for lockbox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE,
+ the original buffer to too small to hold
new information.
+ @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
+ no enough resource to save the information.
@retval RETURN_ACCESS_DENIED it is too late to invoke this interface
@retval RETURN_NOT_STARTED it is too early to invoke this interface
@retval RETURN_UNSUPPORTED the service is not supported by
implementaion.
diff --git a/MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.c
b/MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.c
index c40dfea398..0adda1e2a9 100644
--- a/MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.c
+++ b/MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -76,7 +76,10 @@ SetLockBoxAttributes (
@retval RETURN_SUCCESS the information is saved successfully.
@retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or
Length is 0.
@retval RETURN_NOT_FOUND the requested GUID not found.
- @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold
new information.
+ @retval RETURN_BUFFER_TOO_SMALL for lockbox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE,
+ the original buffer to too small to hold
new information.
+ @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
+ no enough resource to save the information.
@retval RETURN_ACCESS_DENIED it is too late to invoke this interface
@retval RETURN_NOT_STARTED it is too early to invoke this interface
@retval RETURN_UNSUPPORTED the service is not supported by
implementaion.
diff --git a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.c
b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.c
index 0428decbac..5ee563b71f 100644
--- a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.c
+++ b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.c
@@ -300,7 +300,10 @@ SetLockBoxAttributes (
@retval RETURN_SUCCESS the information is saved successfully.
@retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or
Length is 0.
@retval RETURN_NOT_FOUND the requested GUID not found.
- @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold
new information.
+ @retval RETURN_BUFFER_TOO_SMALL for lockbox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE,
+ the original buffer to too small to hold
new information.
+ @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
+ no enough resource to save the information.
@retval RETURN_ACCESS_DENIED it is too late to invoke this interface
@retval RETURN_NOT_STARTED it is too early to invoke this interface
@retval RETURN_UNSUPPORTED the service is not supported by
implementaion.
diff --git a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c
b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c
index 9d7b4c3706..fa558e5c69 100644
--- a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c
+++ b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c
@@ -477,7 +477,10 @@ SetLockBoxAttributes (
@retval RETURN_SUCCESS the information is saved successfully.
@retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or
Length is 0.
@retval RETURN_NOT_FOUND the requested GUID not found.
- @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold
new information.
+ @retval RETURN_BUFFER_TOO_SMALL for lockbox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE,
+ the original buffer to too small to hold
new information.
+ @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
+ no enough resource to save the information.
@retval RETURN_ACCESS_DENIED it is too late to invoke this interface
@retval RETURN_NOT_STARTED it is too early to invoke this interface
@retval RETURN_UNSUPPORTED the service is not supported by
implementaion.
diff --git a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c
b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c
index c912d187a4..095cf8f8a7 100644
--- a/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c
+++ b/MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.c
@@ -604,7 +604,10 @@ SetLockBoxAttributes (
@retval RETURN_SUCCESS the information is saved successfully.
@retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or
Length is 0.
@retval RETURN_NOT_FOUND the requested GUID not found.
- @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold
new information.
+ @retval RETURN_BUFFER_TOO_SMALL for lockbox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE,
+ the original buffer to too small to hold
new information.
+ @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute
LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
+ no enough resource to save the information.
@retval RETURN_ACCESS_DENIED it is too late to invoke this interface
@retval RETURN_NOT_STARTED it is too early to invoke this interface
@retval RETURN_UNSUPPORTED the service is not supported by
implementaion.
@@ -619,6 +622,8 @@ UpdateLockBox (
)
{
SMM_LOCK_BOX_DATA *LockBox;
+ EFI_PHYSICAL_ADDRESS SmramBuffer;
+ EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Enter\n"));
@@ -643,8 +648,54 @@ UpdateLockBox (
// Update data
//
if (LockBox->Length < Offset + Length) {
- DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n",
EFI_BUFFER_TOO_SMALL));
- return EFI_BUFFER_TOO_SMALL;
+ if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY) != 0) {
+ //
+ // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is set,
re-allocate
+ // buffer from SMRAM to expand the LockBox.
+ //
+ DEBUG ((
+ DEBUG_INFO,
+ "SmmLockBoxSmmLib UpdateLockBox - Origin LockBox too small, expand.\n"
+ ));
+
+ //
+ // Allocate new SMRAM buffer
+ //
+ Status = gSmst->SmmAllocatePages (
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES (Offset + Length),
+ &SmramBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
1. Remove the assertion?
2. SaveLockBox() allocates memory in page granularity. So it's possible
that the allocation here is unnecessary. For example:
SaveLockBox() requires 30 bytes. 4K bytes is actually allocated.
UpdateLockBox() requries 50 bytes in total. 4K bytes is required actually.
The original 4K is still enough for the new lock box data.
Maybe we could assume the capacity is always 4K aligned, so the
unnecessary allocation can be avoided in most of the cases.
3. Another thing I am not sure is do we need to check whether
Offset + Length overflows? The check doesn't exist in old code so
it's a off-topic comment.
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n",
EFI_OUT_OF_RESOURCES));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ZeroMem ((VOID *)(UINTN)SmramBuffer, Offset + Length);
+
+ //
+ // Copy origin data to the new SMRAM buffer and wipe the content in the
+ // origin SMRAM
+ //
+ CopyMem ((VOID *)(UINTN)SmramBuffer, (VOID *)(UINTN)LockBox->SmramBuffer,
(UINTN)LockBox->Length);
+ ZeroMem ((VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);
+ gSmst->SmmFreePages (LockBox->SmramBuffer, EFI_SIZE_TO_PAGES
((UINTN)LockBox->Length));
+
+ //
+ // Update information in SMM_LOCK_BOX_DATA structure
+ //
+ LockBox->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
+ LockBox->Length = Offset + Length;
+ LockBox->SmramBuffer = SmramBuffer;
+ } else {
+ //
+ // If 'LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY' attribute is NOT set,
return
+ // EFI_BUFFER_TOO_SMALL directly.
+ //
+ DEBUG ((DEBUG_INFO, "SmmLockBoxSmmLib UpdateLockBox - Exit (%r)\n",
EFI_BUFFER_TOO_SMALL));
+ return EFI_BUFFER_TOO_SMALL;
+ }
}
ASSERT ((UINTN)LockBox->SmramBuffer <= (MAX_ADDRESS - Offset));
CopyMem ((VOID *)((UINTN)LockBox->SmramBuffer + Offset), Buffer, Length);
--
Thanks,
Ray
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel