Skip to content

Commit

Permalink
Rework changes in TestPointStubDxeMm and the MMI handler to not have …
Browse files Browse the repository at this point in the history
…a nested pointer.
  • Loading branch information
kenlautner committed Sep 19, 2023
1 parent bc6b936 commit 7f872ca
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 140 deletions.
5 changes: 3 additions & 2 deletions MinPlatformPkg/Include/Library/TestPointLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,13 @@ typedef struct {
// On output, actual data buffer size copied.
//
UINT64 DataSize;
PHYSICAL_ADDRESS DataBuffer;
//PHYSICAL_ADDRESS DataBuffer;
//
// On input, data buffer offset to copy.
// On output, next time data buffer offset to copy.
//
UINT64 DataOffset;
//UINT64 DataOffset;
UINT8 Data[];
} MMI_HANDLER_TEST_POINT_PARAMETER_GET_DATA_BY_OFFSET;

extern EFI_GUID gAdapterInfoPlatformTestPointGuid;
Expand Down
1 change: 1 addition & 0 deletions MinPlatformPkg/Test/Library/TestPointLib/MmTestPoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <Library/TestPointLib.h>

#include <Protocol/AdapterInformation.h>
#include <Protocol/MmCommunication.h>

#define TEST_POINT_AIP_PRIVATE_SIGNATURE SIGNATURE_32('T', 'S', 'P', 'T')

Expand Down
46 changes: 30 additions & 16 deletions MinPlatformPkg/Test/Library/TestPointLib/MmTestPointCommunication.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,17 +220,21 @@ MmTestPointMmiHandlerGetDataByOffset (
CopyMem (
&MmiHandlerTestPointGetDataByOffset,
MmiHandlerTestPointParameterGetDataByOffset,
sizeof(MmiHandlerTestPointGetDataByOffset)
MmiHandlerTestPointParameterGetDataByOffset->DataSize
);

DEBUG((DEBUG_ERROR, "Struct Buffer Address: %x\n", (UINTN)MmiHandlerTestPointParameterGetDataByOffset));
DEBUG((DEBUG_ERROR, "Struct Data Buffer Address: %x\n", (UINTN)(MmiHandlerTestPointParameterGetDataByOffset->Data)));
DEBUG((DEBUG_ERROR, "STRUCTSIZE: %x\n", sizeof(MMI_HANDLER_TEST_POINT_PARAMETER_GET_DATA_BY_OFFSET)));

//
// Sanity check
//
if (!IsBufferOutsideMmValid((UINTN)MmiHandlerTestPointGetDataByOffset.DataBuffer, (UINTN)MmiHandlerTestPointGetDataByOffset.DataSize)) {
/*if (!IsBufferOutsideMmValid((UINTN)&MmiHandlerTestPointParameterGetDataByOffset->Data[0], (UINTN)*Size)) {
DEBUG((DEBUG_ERROR, "MmTestPointMmiHandlerGetDataByOffset: MmTestPoint get data in SMRAM or overflow!\n"));
MmiHandlerTestPointParameterGetDataByOffset->Header.ReturnStatus = (UINT64)(INT64)(INTN)EFI_ACCESS_DENIED;
MmiHandlerTestPointParameterGetDataByOffset->ReturnStatus = (UINT64)(INT64)(INTN)EFI_ACCESS_DENIED;
goto Done;
}
}*/

DataSize = 0;
Status = GetAllMmTestPointData (&DataSize, NULL);
Expand All @@ -255,18 +259,24 @@ MmTestPointMmiHandlerGetDataByOffset (
// MmiHandlerTestPointCopyData().
//
SpeculationBarrier ();
MmiHandlerTestPointCopyData (
DEBUG((DEBUG_ERROR, "InputSize: %x\n", DataSize));
/*CopyMem (
(VOID *)MmiHandlerTestPointGetDataByOffset.Data,
Data,
DataSize
);*/
/*MmiHandlerTestPointCopyData (
Data,
DataSize,
(VOID *)(UINTN)MmiHandlerTestPointGetDataByOffset.DataBuffer,
&MmiHandlerTestPointGetDataByOffset.DataSize,
&MmiHandlerTestPointGetDataByOffset.DataOffset
);

(VOID *)(UINTN)MmiHandlerTestPointGetDataByOffset.Data,
&(MmiHandlerTestPointGetDataByOffset.DataSize),
0
);*/
DEBUG((DEBUG_ERROR, "DO WE GET HERE?\n"));
CopyMem (
MmiHandlerTestPointParameterGetDataByOffset,
&MmiHandlerTestPointGetDataByOffset,
sizeof(MmiHandlerTestPointGetDataByOffset)
(VOID *)(UINTN)MmiHandlerTestPointParameterGetDataByOffset->Data,
Data,
DataSize
);

MmiHandlerTestPointParameterGetDataByOffset->Header.ReturnStatus = 0;
Expand Down Expand Up @@ -315,13 +325,17 @@ MmTestPointMmiHandler (

TempCommBufferSize = *CommBufferSize;

DEBUG((DEBUG_ERROR, "CommBuffer Real Address: %x\n", (UINTN)CommBuffer));

DEBUG((DEBUG_ERROR, "CommBufferSize: %x, Struct size: %x\n", TempCommBufferSize, sizeof(MMI_HANDLER_TEST_POINT_PARAMETER_GET_DATA_BY_OFFSET)));

if (TempCommBufferSize < sizeof(MMI_HANDLER_TEST_POINT_PARAMETER_HEADER)) {
DEBUG((DEBUG_INFO, "MmTestPointMmiHandler: MM communication buffer size invalid!\n"));
return EFI_SUCCESS;
}

if (!IsCommBufferOutsideMmValid((UINTN)CommBuffer, TempCommBufferSize)) {
DEBUG((DEBUG_INFO, "MmTestPointMmiHandler: MM communication buffer in SMRAM or overflow!\n"));
DEBUG((DEBUG_INFO, "MmTestPointMmiHandler: MM communication buffer in MMRAM or overflow!\n"));
return EFI_SUCCESS;
}

Expand All @@ -339,10 +353,10 @@ MmTestPointMmiHandler (
break;
case MMI_HANDLER_TEST_POINT_COMMAND_GET_DATA_BY_OFFSET:
DEBUG((DEBUG_INFO, "MmiHandlerTestPointHandlerGetDataByOffset\n"));
if (TempCommBufferSize != sizeof(MMI_HANDLER_TEST_POINT_PARAMETER_GET_DATA_BY_OFFSET)) {
/*if (TempCommBufferSize != sizeof(MMI_HANDLER_TEST_POINT_PARAMETER_HEADER)) {
DEBUG((DEBUG_INFO, "MmTestPointMmiHandler: MM communication buffer size invalid!\n"));
return EFI_SUCCESS;
}
}*/
MmTestPointMmiHandlerGetDataByOffset((MMI_HANDLER_TEST_POINT_PARAMETER_GET_DATA_BY_OFFSET *)(UINTN)CommBuffer);
break;
default:
Expand Down
176 changes: 54 additions & 122 deletions MinPlatformPkg/Test/TestPointStubDxe/TestPointStubDxeMm.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@
#include <Library/UefiLib.h>
#include <Library/HobLib.h>
#include <Library/TestPointLib.h>
#include <Library/MmUnblockMemoryLib.h>
#include <Protocol/AdapterInformation.h>
#include <Protocol/MmCommunication.h>
#include <Guid/PiSmmCommunicationRegionTable.h>

UINTN mMmTestPointDatabaseSize;
VOID *mMmTestPointDatabase;
VOID *mMmCommBuffer;

VOID
PublishPeiTestPoint (
Expand Down Expand Up @@ -77,8 +75,10 @@ GetTestPointDataMm (
EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;
UINT32 Index;
EFI_MEMORY_DESCRIPTOR *Entry;
//VOID *Buffer;
UINTN Size;
UINTN Offset;
//UINTN Offset;
//MMI_HANDLER_TEST_POINT_PARAMETER_HEADER_2 *HeaderInfo;

Status = gBS->LocateProtocol(&gEfiMmCommunicationProtocolGuid, NULL, (VOID **)&MmCommunication);
if (EFI_ERROR(Status)) {
Expand Down Expand Up @@ -110,6 +110,7 @@ GetTestPointDataMm (
}
ASSERT(Index < PiSmmCommunicationRegionTable->NumberOfEntries);
CommBuffer = (UINT8 *)(UINTN)Entry->PhysicalStart;
DEBUG((DEBUG_ERROR, "CommBuffer Address: %x\n", (UINT32)Entry->PhysicalStart));

//
// Get Size
Expand All @@ -125,7 +126,6 @@ GetTestPointDataMm (
CommGetInfo->DataSize = 0;

CommSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + (UINTN)CommHeader->MessageLength;

Status = MmCommunication->Communicate(MmCommunication, CommBuffer, &CommSize);
if (EFI_ERROR(Status)) {
DEBUG ((DEBUG_INFO, "MmiHandlerTestPoint: MmCommunication - %r\n", Status));
Expand All @@ -149,21 +149,65 @@ GetTestPointDataMm (
return ;
}

//ZeroMem (CommBuffer, Size);

CommHeader = (EFI_MM_COMMUNICATE_HEADER *)&CommBuffer[0];
CopyMem(&CommHeader->HeaderGuid, &gAdapterInfoPlatformTestPointGuid, sizeof(gAdapterInfoPlatformTestPointGuid));
CommHeader->MessageLength = sizeof(MMI_HANDLER_TEST_POINT_PARAMETER_GET_DATA_BY_OFFSET);
CommHeader->MessageLength = sizeof(MMI_HANDLER_TEST_POINT_PARAMETER_GET_DATA_BY_OFFSET) + mMmTestPointDatabaseSize;

CommGetData = (MMI_HANDLER_TEST_POINT_PARAMETER_GET_DATA_BY_OFFSET *)&CommBuffer[OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data)];
CommGetData->Header.Command = MMI_HANDLER_TEST_POINT_COMMAND_GET_DATA_BY_OFFSET;
CommGetData->Header.DataLength = sizeof(*CommGetData);
CommGetData->Header.ReturnStatus = (UINT64)-1;

CommSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + (UINTN)CommHeader->MessageLength;
DEBUG((DEBUG_ERROR, "Offset size: %x, MessageLength: %x, CommSize: %x\n", OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data), (UINTN)CommHeader->MessageLength, CommSize));
//Buffer = (UINT8 *)CommHeader + CommSize;
Size -= CommSize;

CommGetData->DataBuffer = (PHYSICAL_ADDRESS)(UINTN)mMmCommBuffer;
CommGetData->DataOffset = 0;
while (CommGetData->DataOffset < mMmTestPointDatabaseSize) {
//CommGetData->DataBuffer = (PHYSICAL_ADDRESS)(UINTN)Buffer;
//CommGetData->DataOffset = 0;



/*CommHeader->MessageLength = Size - OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
DEBUG((DEBUG_ERROR, "MessageLength: %x\n", CommHeader->MessageLength));
HeaderInfo = (MMI_HANDLER_TEST_POINT_PARAMETER_HEADER_2 *)CommHeader->Data;
HeaderInfo->Command = MMI_HANDLER_TEST_POINT_COMMAND_GET_DATA_BY_OFFSET;
if (CommHeader->MessageLength > mMmTestPointDatabaseSize) {
CommHeader->MessageLength = mMmTestPointDatabaseSize;
}
CommSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + (UINTN)CommHeader->MessageLength;
DEBUG((DEBUG_ERROR, "Size: %x, CommSize: %x, MessageLength: %x\n", Size, CommSize, CommHeader->MessageLength));
Status = MmCommunication->Communicate(MmCommunication, CommBuffer, &CommSize);
ASSERT_EFI_ERROR(Status);
CopyMem((UINT8 *)mMmTestPointDatabase, (VOID *)(UINTN)&HeaderInfo->Data[0], (UINTN)CommHeader->MessageLength);*/

/*if (Size <= (mMmTestPointDatabaseSize)) {
CommGetData->DataSize = (UINT64)Size;
} else {
CommGetData->DataSize = (UINT64)(mMmTestPointDatabaseSize);
}*/
CommGetData->DataSize = (UINT64)(mMmTestPointDatabaseSize);
DEBUG((DEBUG_ERROR, "Buffer Size: %x\n", Size));
Status = MmCommunication->Communicate(MmCommunication, CommBuffer, &CommSize);
ASSERT_EFI_ERROR(Status);

if (CommGetData->Header.ReturnStatus != 0) {
FreePool(mMmTestPointDatabase);
mMmTestPointDatabase = NULL;
DEBUG ((DEBUG_INFO, "MmiHandlerTestPoint: GetData - 0x%x\n", CommGetData->Header.ReturnStatus));
return ;
}
CopyMem((UINT8 *)mMmTestPointDatabase, (VOID *)(UINTN)CommGetData->Data, (UINTN)CommGetData->DataSize);

/*while (CommGetData->DataOffset < mMmTestPointDatabaseSize) {
Offset = (UINTN)CommGetData->DataOffset;
if (Size <= (mMmTestPointDatabaseSize - CommGetData->DataOffset)) {
CommGetData->DataSize = (UINT64)Size;
Expand All @@ -180,7 +224,7 @@ GetTestPointDataMm (
return ;
}
CopyMem((UINT8 *)mMmTestPointDatabase + Offset, (VOID *)(UINTN)CommGetData->DataBuffer, (UINTN)CommGetData->DataSize);
}
}*/

DEBUG ((DEBUG_INFO, "MmTestPointDatabaseSize - 0x%x\n", mMmTestPointDatabaseSize));

Expand Down Expand Up @@ -242,117 +286,6 @@ PublishMmTestPoint (
}
}

/**
Notification function of END_OF_DXE event group.
This is a notification function registered on END_OF_DXE event group.
When End of DXE is signalled we get the size of the PiSmmCommunicationRegionTable
to allocate a runtime buffer used for communicating the MM Testpoint results.
This requires the allocated pages to be unblocked for MM which must occur before
ReadyToLock.
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
VOID
EFIAPI
OnEndOfDxe (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINTN CommSize;
EFI_MM_COMMUNICATION_PROTOCOL *MmCommunication;
UINTN MinimalSizeNeeded;
EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;
UINT32 Index;
EFI_MEMORY_DESCRIPTOR *Entry;
UINTN Size;

Status = gBS->LocateProtocol(&gEfiMmCommunicationProtocolGuid, NULL, (VOID **)&MmCommunication);
if (EFI_ERROR(Status)) {
DEBUG ((DEBUG_ERROR, "MmiHandlerTestPoint: Locate MmCommunication protocol - %r\n", Status));
return ;
}

MinimalSizeNeeded = EFI_PAGE_SIZE;

Status = EfiGetSystemConfigurationTable(
&gEdkiiPiSmmCommunicationRegionTableGuid,
(VOID **)&PiSmmCommunicationRegionTable
);
if (EFI_ERROR(Status)) {
DEBUG ((DEBUG_ERROR, "MmiHandlerTestPoint: Get PiSmmCommunicationRegionTable - %r\n", Status));
return ;
}
if (PiSmmCommunicationRegionTable == NULL) {
DEBUG ((DEBUG_ERROR, "Failed to get the PiSmmCommunicationRegionTable.\n"));
ASSERT(PiSmmCommunicationRegionTable != NULL);
return ;
}
Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1);
Size = 0;
for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {
if (Entry->Type == EfiConventionalMemory) {
Size = EFI_PAGES_TO_SIZE((UINTN)Entry->NumberOfPages);
if (Size >= MinimalSizeNeeded) {
break;
}
}
Entry = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Entry + PiSmmCommunicationRegionTable->DescriptorSize);
}
ASSERT(Index < PiSmmCommunicationRegionTable->NumberOfEntries);
if (Size < MinimalSizeNeeded) {
DEBUG ((DEBUG_ERROR, "Failed to find any entries in the PiSmmCommunicationRegionTable.\n"));
return ;
}

CommSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + sizeof(MMI_HANDLER_TEST_POINT_PARAMETER_GET_DATA_BY_OFFSET);

Size -= CommSize;
mMmCommBuffer = AllocateRuntimeZeroPool(Size);

//
// Request to unblock the newly allocated cache region to be accessible from inside MM
//
Status = MmUnblockMemoryRequest (
(EFI_PHYSICAL_ADDRESS) ALIGN_VALUE ((UINTN)mMmCommBuffer - EFI_PAGE_SIZE + 1, EFI_PAGE_SIZE),
EFI_SIZE_TO_PAGES (Size)
);
if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Failed to unblock memory!\n"));
return;
}
}


/**
Notification function of END_OF_DXE event group.
This is required to unblock pages before ReadyToLock occurs
**/
VOID
TestPointUnblockCall (
VOID
)
{
EFI_STATUS Status;
EFI_EVENT EndOfDxeEvent;

Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
OnEndOfDxe,
NULL,
&gEfiEndOfDxeEventGroupGuid,
&EndOfDxeEvent
);

ASSERT_EFI_ERROR (Status);
}

/**
Notification function of EVT_GROUP_READY_TO_BOOT event group.
It runs after most ReadyToBoot event signaled.
Expand Down Expand Up @@ -449,7 +382,6 @@ TestPointStubDxeMmEntryPoint (
{
TestPointStubForPei ();
TestPointStubForMm ();
TestPointUnblockCall ();

return EFI_SUCCESS;
}
}

0 comments on commit 7f872ca

Please sign in to comment.