summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStar Zeng <star.zeng@intel.com>2016-04-22 15:16:46 +0800
committerHao Wu <hao.a.wu@intel.com>2016-07-06 16:19:47 +0800
commitd11e1db0d96425e5e49bb47fd39450a32b280013 (patch)
tree99184b5fc4627e9e329aa18326ad8fa77eb1b57d
parent174906b50d277afd55f4445e876cc23374d15cbf (diff)
downloadedk2-platforms-d11e1db0d96425e5e49bb47fd39450a32b280013.tar.xz
MdeModulePkg-MemoryProfile(2): Add SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET in PiSmmCore.
This patch enhance SMM memory profile SMM communication by using fixed SMM communication buffer. Update PiSmmCore to handle SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET request. This is designed to meet Microsoft WSMT table definition on FIXED_COMM_BUFFERS requirement. Cc: Star Zeng <star.zeng@intel.com> Cc: Feng Tian <feng.tian@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com> Regression-tested-by: Laszlo Ersek <lersek@redhat.com> (cherry picked from commit c3592c86ee39c3582f1d4c6b31cf91113e9d4c5f)
-rw-r--r--MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c247
1 files changed, 204 insertions, 43 deletions
diff --git a/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c b/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c
index 72fd37ece5..57b34a018d 100644
--- a/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c
+++ b/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c
@@ -1,7 +1,7 @@
/** @file
Support routines for SMRAM profile.
- Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
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
@@ -1256,11 +1256,17 @@ SmramProfileGetDataSize (
Copy SMRAM profile data.
@param ProfileBuffer The buffer to hold SMRAM profile data.
+ @param ProfileSize On input, profile buffer size.
+ On output, actual profile data size copied.
+ @param ProfileOffset On input, profile buffer offset to copy.
+ On output, next time profile buffer offset to copy.
**/
VOID
SmramProfileCopyData (
- IN VOID *ProfileBuffer
+ OUT VOID *ProfileBuffer,
+ IN OUT UINT64 *ProfileSize,
+ IN OUT UINT64 *ProfileOffset
)
{
MEMORY_PROFILE_CONTEXT *Context;
@@ -1283,15 +1289,28 @@ SmramProfileCopyData (
MEMORY_PROFILE_FREE_MEMORY *FreeMemory;
MEMORY_PROFILE_MEMORY_RANGE *MemoryRange;
MEMORY_PROFILE_DESCRIPTOR *MemoryProfileDescriptor;
+ UINT64 Offset;
+ UINT64 RemainingSize;
ContextData = GetSmramProfileContext ();
if (ContextData == NULL) {
return ;
}
- Context = ProfileBuffer;
- CopyMem (Context, &ContextData->Context, sizeof (MEMORY_PROFILE_CONTEXT));
- DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) (Context + 1);
+ RemainingSize = *ProfileSize;
+ Offset = 0;
+
+ if (*ProfileOffset < sizeof (MEMORY_PROFILE_CONTEXT)) {
+ if (RemainingSize >= sizeof (MEMORY_PROFILE_CONTEXT)) {
+ Context = ProfileBuffer;
+ CopyMem (Context, &ContextData->Context, sizeof (MEMORY_PROFILE_CONTEXT));
+ RemainingSize -= sizeof (MEMORY_PROFILE_CONTEXT);
+ ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_CONTEXT);
+ } else {
+ goto Done;
+ }
+ }
+ Offset += sizeof (MEMORY_PROFILE_CONTEXT);
DriverInfoList = ContextData->DriverInfoList;
for (DriverLink = DriverInfoList->ForwardLink;
@@ -1303,8 +1322,17 @@ SmramProfileCopyData (
Link,
MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
);
- CopyMem (DriverInfo, &DriverInfoData->DriverInfo, sizeof (MEMORY_PROFILE_DRIVER_INFO));
- AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *) (DriverInfo + 1);
+ if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DRIVER_INFO))) {
+ if (RemainingSize >= sizeof (MEMORY_PROFILE_DRIVER_INFO)) {
+ DriverInfo = ProfileBuffer;
+ CopyMem (DriverInfo, &DriverInfoData->DriverInfo, sizeof (MEMORY_PROFILE_DRIVER_INFO));
+ RemainingSize -= sizeof (MEMORY_PROFILE_DRIVER_INFO);
+ ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DRIVER_INFO);
+ } else {
+ goto Done;
+ }
+ }
+ Offset += sizeof (MEMORY_PROFILE_DRIVER_INFO);
AllocInfoList = DriverInfoData->AllocInfoList;
for (AllocLink = AllocInfoList->ForwardLink;
@@ -1316,30 +1344,73 @@ SmramProfileCopyData (
Link,
MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
);
- CopyMem (AllocInfo, &AllocInfoData->AllocInfo, sizeof (MEMORY_PROFILE_ALLOC_INFO));
- AllocInfo += 1;
+ if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_ALLOC_INFO))) {
+ if (RemainingSize >= sizeof (MEMORY_PROFILE_ALLOC_INFO)) {
+ AllocInfo = ProfileBuffer;
+ CopyMem (AllocInfo, &AllocInfoData->AllocInfo, sizeof (MEMORY_PROFILE_ALLOC_INFO));
+ RemainingSize -= sizeof (MEMORY_PROFILE_ALLOC_INFO);
+ ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_ALLOC_INFO);
+ } else {
+ goto Done;
+ }
+ }
+ Offset += sizeof (MEMORY_PROFILE_ALLOC_INFO);
}
-
- DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) ((UINTN) (DriverInfo + 1) + sizeof (MEMORY_PROFILE_ALLOC_INFO) * (UINTN) DriverInfo->AllocRecordCount);
}
- FreeMemory = (MEMORY_PROFILE_FREE_MEMORY *) DriverInfo;
- CopyMem (FreeMemory, &mSmramFreeMemory, sizeof (MEMORY_PROFILE_FREE_MEMORY));
- MemoryProfileDescriptor = (MEMORY_PROFILE_DESCRIPTOR *) (FreeMemory + 1);
- Index = 0;
+ if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_FREE_MEMORY))) {
+ if (RemainingSize >= sizeof (MEMORY_PROFILE_FREE_MEMORY)) {
+ FreeMemory = ProfileBuffer;
+ CopyMem (FreeMemory, &mSmramFreeMemory, sizeof (MEMORY_PROFILE_FREE_MEMORY));
+ Index = 0;
+ FreePageList = &mSmmMemoryMap;
+ for (Node = FreePageList->BackLink;
+ Node != FreePageList;
+ Node = Node->BackLink) {
+ Index++;
+ }
+ for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) {
+ FreePoolList = &mSmmPoolLists[MAX_POOL_INDEX - PoolListIndex - 1];
+ for (Node = FreePoolList->BackLink;
+ Node != FreePoolList;
+ Node = Node->BackLink) {
+ Pool = BASE_CR (Node, FREE_POOL_HEADER, Link);
+ if (Pool->Header.Available) {
+ Index++;
+ }
+ }
+ }
+ FreeMemory->FreeMemoryEntryCount = Index;
+
+ RemainingSize -= sizeof (MEMORY_PROFILE_FREE_MEMORY);
+ ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_FREE_MEMORY);
+ } else {
+ goto Done;
+ }
+ }
+ Offset += sizeof (MEMORY_PROFILE_FREE_MEMORY);
FreePageList = &mSmmMemoryMap;
for (Node = FreePageList->BackLink;
Node != FreePageList;
Node = Node->BackLink) {
- Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);
- MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;
- MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);
- MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;
- MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pages;
- MemoryProfileDescriptor->Size = EFI_PAGES_TO_SIZE (Pages->NumberOfPages);
- MemoryProfileDescriptor++;
- Index++;
+ if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) {
+ if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) {
+ Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);
+ MemoryProfileDescriptor = ProfileBuffer;
+ MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;
+ MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);
+ MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;
+ MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pages;
+ MemoryProfileDescriptor->Size = EFI_PAGES_TO_SIZE (Pages->NumberOfPages);
+
+ RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR);
+ ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR);
+ } else {
+ goto Done;
+ }
+ }
+ Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR);
}
for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) {
FreePoolList = &mSmmPoolLists[MAX_POOL_INDEX - PoolListIndex - 1];
@@ -1348,32 +1419,69 @@ SmramProfileCopyData (
Node = Node->BackLink) {
Pool = BASE_CR (Node, FREE_POOL_HEADER, Link);
if (Pool->Header.Available) {
+ if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) {
+ if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) {
+ MemoryProfileDescriptor = ProfileBuffer;
+ MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;
+ MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);
+ MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;
+ MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pool;
+ MemoryProfileDescriptor->Size = Pool->Header.Size;
+
+ RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR);
+ ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR);
+ } else {
+ goto Done;
+ }
+ }
+ Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR);
+ }
+ }
+ }
+
+ if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_MEMORY_RANGE))) {
+ if (RemainingSize >= sizeof (MEMORY_PROFILE_MEMORY_RANGE)) {
+ MemoryRange = ProfileBuffer;
+ MemoryRange->Header.Signature = MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE;
+ MemoryRange->Header.Length = sizeof (MEMORY_PROFILE_MEMORY_RANGE);
+ MemoryRange->Header.Revision = MEMORY_PROFILE_MEMORY_RANGE_REVISION;
+ MemoryRange->MemoryRangeCount = (UINT32) mFullSmramRangeCount;
+
+ RemainingSize -= sizeof (MEMORY_PROFILE_MEMORY_RANGE);
+ ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_MEMORY_RANGE);
+ } else {
+ goto Done;
+ }
+ }
+ Offset += sizeof (MEMORY_PROFILE_MEMORY_RANGE);
+ for (Index = 0; Index < mFullSmramRangeCount; Index++) {
+ if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) {
+ if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) {
+ MemoryProfileDescriptor = ProfileBuffer;
MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;
MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);
MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;
- MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pool;
- MemoryProfileDescriptor->Size = Pool->Header.Size;
- MemoryProfileDescriptor++;
- Index++;
+ MemoryProfileDescriptor->Address = mFullSmramRanges[Index].PhysicalStart;
+ MemoryProfileDescriptor->Size = mFullSmramRanges[Index].PhysicalSize;
+
+ RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR);
+ ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR);
+ } else {
+ goto Done;
}
}
+ Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR);
}
- FreeMemory->FreeMemoryEntryCount = Index;
- MemoryRange = (MEMORY_PROFILE_MEMORY_RANGE *) MemoryProfileDescriptor;
- MemoryRange->Header.Signature = MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE;
- MemoryRange->Header.Length = sizeof (MEMORY_PROFILE_MEMORY_RANGE);
- MemoryRange->Header.Revision = MEMORY_PROFILE_MEMORY_RANGE_REVISION;
- MemoryRange->MemoryRangeCount = (UINT32) mFullSmramRangeCount;
- MemoryProfileDescriptor = (MEMORY_PROFILE_DESCRIPTOR *) (MemoryRange + 1);
- for (Index = 0; Index < mFullSmramRangeCount; Index++) {
- MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE;
- MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR);
- MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION;
- MemoryProfileDescriptor->Address = mFullSmramRanges[Index].PhysicalStart;
- MemoryProfileDescriptor->Size = mFullSmramRanges[Index].PhysicalSize;
- MemoryProfileDescriptor++;
- }
+Done:
+ //
+ // On output, actual profile data size copied.
+ //
+ *ProfileSize -= RemainingSize;
+ //
+ // On output, next time profile buffer offset to copy.
+ //
+ *ProfileOffset = Offset;
}
/**
@@ -1416,6 +1524,7 @@ SmramProfileHandlerGetData (
)
{
UINT64 ProfileSize;
+ UINT64 ProfileOffset;
SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA SmramProfileGetData;
MEMORY_PROFILE_CONTEXT_DATA *ContextData;
BOOLEAN SmramProfileRecordingStatus;
@@ -1449,8 +1558,9 @@ SmramProfileHandlerGetData (
goto Done;
}
+ ProfileOffset = 0;
+ SmramProfileCopyData ((VOID *) (UINTN) SmramProfileGetData.ProfileBuffer, &ProfileSize, &ProfileOffset);
SmramProfileParameterGetData->ProfileSize = ProfileSize;
- SmramProfileCopyData ((VOID *) (UINTN) SmramProfileGetData.ProfileBuffer);
SmramProfileParameterGetData->Header.ReturnStatus = 0;
Done:
@@ -1458,6 +1568,49 @@ Done:
}
/**
+ SMRAM profile handler to get profile data by offset.
+
+ @param SmramProfileParameterGetDataByOffset The parameter of SMM profile get data by offset.
+
+**/
+VOID
+SmramProfileHandlerGetDataByOffset (
+ IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *SmramProfileParameterGetDataByOffset
+ )
+{
+ SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET SmramProfileGetDataByOffset;
+ MEMORY_PROFILE_CONTEXT_DATA *ContextData;
+ BOOLEAN SmramProfileRecordingStatus;
+
+ ContextData = GetSmramProfileContext ();
+ if (ContextData == NULL) {
+ return ;
+ }
+
+ SmramProfileRecordingStatus = mSmramProfileRecordingStatus;
+ mSmramProfileRecordingStatus = FALSE;
+
+
+ CopyMem (&SmramProfileGetDataByOffset, SmramProfileParameterGetDataByOffset, sizeof (SmramProfileGetDataByOffset));
+
+ //
+ // Sanity check
+ //
+ if (!SmmIsBufferOutsideSmmValid ((UINTN) SmramProfileGetDataByOffset.ProfileBuffer, (UINTN) SmramProfileGetDataByOffset.ProfileSize)) {
+ DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetDataByOffset: SMM ProfileBuffer in SMRAM or overflow!\n"));
+ SmramProfileParameterGetDataByOffset->Header.ReturnStatus = (UINT64) (INT64) (INTN) EFI_ACCESS_DENIED;
+ goto Done;
+ }
+
+ SmramProfileCopyData ((VOID *) (UINTN) SmramProfileGetDataByOffset.ProfileBuffer, &SmramProfileGetDataByOffset.ProfileSize, &SmramProfileGetDataByOffset.ProfileOffset);
+ CopyMem (SmramProfileParameterGetDataByOffset, &SmramProfileGetDataByOffset, sizeof (SmramProfileGetDataByOffset));
+ SmramProfileParameterGetDataByOffset->Header.ReturnStatus = 0;
+
+Done:
+ mSmramProfileRecordingStatus = SmramProfileRecordingStatus;
+}
+
+/**
SMRAM profile handler to register SMM image.
@param SmramProfileParameterRegisterImage The parameter of SMM profile register image.
@@ -1592,6 +1745,14 @@ SmramProfileHandler (
}
SmramProfileHandlerGetData ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *) (UINTN) CommBuffer);
break;
+ case SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET:
+ DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetDataByOffset\n"));
+ if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET)) {
+ DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
+ return EFI_SUCCESS;
+ }
+ SmramProfileHandlerGetDataByOffset ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *) (UINTN) CommBuffer);
+ break;
case SMRAM_PROFILE_COMMAND_REGISTER_IMAGE:
DEBUG ((EFI_D_ERROR, "SmramProfileHandlerRegisterImage\n"));
if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE)) {