diff options
author | Wei6 Xu <wei6.xu@intel.com> | 2024-05-13 23:51:45 +0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2024-08-28 15:25:27 +0000 |
commit | 24e41d1fa3e08972ced64617df651b105411e13a (patch) | |
tree | 15a963691f1c51f931fe3a030131969d3b2483c3 /StandaloneMmPkg | |
parent | 68487b4736291e3f3efc5181e1b13d0b63bffe80 (diff) | |
download | edk2-24e41d1fa3e08972ced64617df651b105411e13a.tar.gz |
StandaloneMmPkg/Core: Introduce MM Communication Buffer
Get the MM Communication context from the MM Communication Buffer,
instead of the pointer inside gMmCorePrivate.
In the MmEntryPoint, check IsCommBufferValid from MM_COMM_BUFFER to
decide whether the MMI is Synchronous MMI or Asynchronous MMI. If it
is a Synchronous MMI, MM Core shadows the communication buffer into
a internal copy, then invokes the MMI handlers, lastly copies data
back to the MM Communication Buffer and set the return status.
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
Diffstat (limited to 'StandaloneMmPkg')
-rw-r--r-- | StandaloneMmPkg/Core/StandaloneMmCore.c | 142 | ||||
-rw-r--r-- | StandaloneMmPkg/Core/StandaloneMmCore.h | 1 | ||||
-rw-r--r-- | StandaloneMmPkg/Core/StandaloneMmCore.inf | 1 |
3 files changed, 120 insertions, 24 deletions
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index 14e76fa67e..7e129832fc 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -88,6 +88,8 @@ MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = { UINTN mMmramRangeCount;
EFI_MMRAM_DESCRIPTOR *mMmramRanges;
+MM_COMM_BUFFER *mMmCommunicationBuffer;
+VOID *mInternalCommBufferCopy;
/**
Place holder function until all the MM System Table Service are available.
@@ -398,6 +400,62 @@ MmCoreInstallLoadedImage ( }
/**
+ Prepare communication buffer for MMI.
+**/
+VOID
+MmCorePrepareCommunicationBuffer (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ EFI_PHYSICAL_ADDRESS Buffer;
+
+ mMmCommunicationBuffer = NULL;
+ mInternalCommBufferCopy = NULL;
+
+ GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid);
+ ASSERT (GuidHob != NULL);
+ if (GuidHob == NULL) {
+ return;
+ }
+
+ mMmCommunicationBuffer = (MM_COMM_BUFFER *)GET_GUID_HOB_DATA (GuidHob);
+ DEBUG ((
+ DEBUG_INFO,
+ "MM Communication Buffer is at %x, number of pages is %x\n",
+ mMmCommunicationBuffer->PhysicalStart,
+ mMmCommunicationBuffer->NumberOfPages
+ ));
+ ASSERT (mMmCommunicationBuffer->PhysicalStart != 0 && mMmCommunicationBuffer->NumberOfPages != 0);
+
+ if (!MmIsBufferOutsideMmValid (
+ mMmCommunicationBuffer->PhysicalStart,
+ EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)
+ ))
+ {
+ mMmCommunicationBuffer = NULL;
+ DEBUG ((DEBUG_ERROR, "MM Communication Buffer is invalid!\n"));
+ ASSERT (FALSE);
+ return;
+ }
+
+ Status = MmAllocatePages (
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ mMmCommunicationBuffer->NumberOfPages,
+ &Buffer
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ mInternalCommBufferCopy = (VOID *)(UINTN)Buffer;
+ DEBUG ((DEBUG_INFO, "Internal Communication Buffer Copy is at %p\n", mInternalCommBufferCopy));
+}
+
+/**
The main entry point to MM Foundation.
Note: This function is only used by MMRAM invocation. It is never used by DXE invocation.
@@ -414,6 +472,8 @@ MmEntryPoint ( {
EFI_STATUS Status;
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
+ MM_COMM_BUFFER_STATUS *CommunicationStatus;
+ UINTN BufferSize;
DEBUG ((DEBUG_INFO, "MmEntryPoint ...\n"));
@@ -440,33 +500,65 @@ MmEntryPoint ( // Check to see if this is a Synchronous MMI sent through the MM Communication
// Protocol or an Asynchronous MMI
//
- if (gMmCorePrivate->CommunicationBuffer != 0) {
- //
- // Synchronous MMI for MM Core or request from Communicate protocol
- //
- if (!MmIsBufferOutsideMmValid ((UINTN)gMmCorePrivate->CommunicationBuffer, gMmCorePrivate->BufferSize)) {
- //
- // If CommunicationBuffer is not in valid address scope, return EFI_INVALID_PARAMETER
- //
- gMmCorePrivate->CommunicationBuffer = 0;
- gMmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER;
- } else {
- CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)gMmCorePrivate->CommunicationBuffer;
- gMmCorePrivate->BufferSize -= OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
- Status = MmiManage (
- &CommunicateHeader->HeaderGuid,
- NULL,
- CommunicateHeader->Data,
- (UINTN *)&gMmCorePrivate->BufferSize
- );
+ if ((mMmCommunicationBuffer != NULL) && (mInternalCommBufferCopy != NULL)) {
+ CommunicationStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)mMmCommunicationBuffer->Status;
+ if (CommunicationStatus->IsCommBufferValid) {
//
- // Update CommunicationBuffer, BufferSize and ReturnStatus
- // Communicate service finished, reset the pointer to CommBuffer to NULL
+ // Synchronous MMI for MM Core or request from Communicate protocol
//
- gMmCorePrivate->BufferSize += OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
- gMmCorePrivate->CommunicationBuffer = 0;
- gMmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
+ CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mMmCommunicationBuffer->PhysicalStart;
+ BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+ if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) {
+ //
+ // Shadow the data from MM Communication Buffer to internal buffer
+ //
+ CopyMem (
+ mInternalCommBufferCopy,
+ (VOID *)(UINTN)mMmCommunicationBuffer->PhysicalStart,
+ BufferSize
+ );
+ ZeroMem (
+ (UINT8 *)mInternalCommBufferCopy + BufferSize,
+ EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages) - BufferSize
+ );
+
+ CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mInternalCommBufferCopy;
+ BufferSize = CommunicateHeader->MessageLength;
+ Status = MmiManage (
+ &CommunicateHeader->HeaderGuid,
+ NULL,
+ CommunicateHeader->Data,
+ &BufferSize
+ );
+
+ BufferSize = BufferSize + OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
+ if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) {
+ //
+ // Copy the data back to MM Communication Buffer
+ //
+ CopyMem (
+ (VOID *)(UINTN)mMmCommunicationBuffer->PhysicalStart,
+ mInternalCommBufferCopy,
+ BufferSize
+ );
+ } else {
+ DEBUG ((DEBUG_ERROR, "Returned buffer size is larger than the size of MM Communication Buffer\n"));
+ ASSERT (FALSE);
+ }
+
+ //
+ // Update CommunicationBuffer, BufferSize and ReturnStatus
+ // Communicate service finished, reset the pointer to CommBuffer to NULL
+ //
+ CommunicationStatus->ReturnBufferSize = BufferSize;
+ CommunicationStatus->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
+ } else {
+ DEBUG ((DEBUG_ERROR, "Input buffer size is larger than the size of MM Communication Buffer\n"));
+ ASSERT (FALSE);
+ }
}
+ } else {
+ DEBUG ((DEBUG_ERROR, "No valid communication buffer, no Synchronous MMI will be processed\n"));
}
//
@@ -738,6 +830,8 @@ StandaloneMmMain ( DEBUG ((DEBUG_INFO, "MmiHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status));
}
+ MmCorePrepareCommunicationBuffer ();
+
//
// Install Loaded Image Protocol form MM Core
//
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index c08d1d76c0..1d34bb643e 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -30,6 +30,7 @@ #include <Guid/HobList.h>
#include <Guid/MmFvDispatch.h>
#include <Guid/MmramMemoryReserve.h>
+#include <Guid/MmCommBuffer.h>
#include <Library/StandaloneMmCoreEntryPoint.h>
#include <Library/BaseLib.h>
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index 8cc9638db5..726a946883 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -76,6 +76,7 @@ gEfiEventLegacyBootGuid
gEfiEventExitBootServicesGuid
gEfiEventReadyToBootGuid
+ gMmCommBufferHobGuid
[Pcd]
gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES
|