summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKun Qin <kuqin@microsoft.com>2024-08-07 09:40:12 -0700
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2025-04-07 07:42:13 +0000
commit05f47b8486d09315d461cb7639694d774871d2c1 (patch)
tree4446e35a2f7c867ae4de79a062298cfe3fa8f86f
parent249ca10af0f4930f63601eb4e4a1f2106e2db2d9 (diff)
downloadedk2-05f47b8486d09315d461cb7639694d774871d2c1.zip
edk2-05f47b8486d09315d461cb7639694d774871d2c1.tar.gz
edk2-05f47b8486d09315d461cb7639694d774871d2c1.tar.bz2
MdeModulePkg: PiSmmIpl: Update MessageLength calculation for MmCommunicate
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3398 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3430 This change added support of installing `EFI_MM_COMMUNICATION3_PROTOCOL`. MmCommunicate v3 routine that calculates message length is also updated to remove ambiguity in contrast to v1 routine. Signed-off-by: Kun Qin <kuqin12@gmail.com>
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c126
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf2
2 files changed, 114 insertions, 14 deletions
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c
index fbba868..e801b75 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c
@@ -11,6 +11,7 @@
#include <Protocol/SmmBase2.h>
#include <Protocol/SmmCommunication.h>
#include <Protocol/MmCommunication2.h>
+#include <Protocol/MmCommunication3.h>
#include <Protocol/SmmAccess2.h>
#include <Protocol/SmmConfiguration.h>
#include <Protocol/SmmControl2.h>
@@ -147,6 +148,37 @@ SmmCommunicationMmCommunicate2 (
);
/**
+ Communicates with a registered handler.
+
+ This function provides a service to send and receive messages from a registered UEFI service.
+
+ @param[in] This The EFI_MM_COMMUNICATION3_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+ @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicationMmCommunicate3 (
+ IN CONST EFI_MM_COMMUNICATION3_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual
+ );
+
+/**
Event notification that is fired every time a gEfiSmmConfigurationProtocol installs.
@param Event The Event that is being processed, not used.
@@ -276,6 +308,13 @@ EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = {
};
//
+// PI 1.9 MM Communication Protocol 3 instance
+//
+EFI_MM_COMMUNICATION3_PROTOCOL mMmCommunication3 = {
+ MmCommunicationMmCommunicate3
+};
+
+//
// SMM Core Private Data structure that contains the data shared between
// the SMM IPL and the SMM Core.
//
@@ -511,10 +550,12 @@ SmmCommunicationCommunicate (
IN OUT UINTN *CommSize OPTIONAL
)
{
- EFI_STATUS Status;
- EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;
- BOOLEAN OldInSmm;
- UINTN TempCommSize;
+ EFI_STATUS Status;
+ EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;
+ EFI_MM_COMMUNICATE_HEADER_V3 *CommunicateHeaderV3 = NULL;
+ BOOLEAN OldInSmm;
+ UINTN TempCommSize;
+ UINTN CommHeaderSize;
//
// Check parameters
@@ -524,17 +565,28 @@ SmmCommunicationCommunicate (
}
CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommBuffer;
+ if (CompareGuid (&CommunicateHeader->HeaderGuid, &gEfiMmCommunicateHeaderV3Guid)) {
+ CommunicateHeaderV3 = (EFI_MM_COMMUNICATE_HEADER_V3 *)CommBuffer;
+ if (CommunicateHeaderV3->BufferSize < sizeof (EFI_MM_COMMUNICATE_HEADER_V3) + CommunicateHeaderV3->MessageSize) {
+ return EFI_INVALID_PARAMETER;
+ }
- if (CommSize == NULL) {
- TempCommSize = OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+ TempCommSize = (UINTN)CommunicateHeaderV3->BufferSize;
+ CommHeaderSize = sizeof (EFI_MM_COMMUNICATE_HEADER_V3);
} else {
- TempCommSize = *CommSize;
- //
- // CommSize must hold HeaderGuid and MessageLength
- //
- if (TempCommSize < OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) {
- return EFI_INVALID_PARAMETER;
+ if (CommSize == NULL) {
+ TempCommSize = OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
+ } else {
+ TempCommSize = *CommSize;
+ //
+ // CommSize must hold HeaderGuid and MessageLength
+ //
+ if (TempCommSize < OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) {
+ return EFI_INVALID_PARAMETER;
+ }
}
+
+ CommHeaderSize = OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
}
//
@@ -591,18 +643,22 @@ SmmCommunicationCommunicate (
//
// Before SetVirtualAddressMap(), we are in SMM or SMRAM is open and unlocked, call SmiManage() directly.
//
- TempCommSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
+ TempCommSize -= CommHeaderSize;
Status = gSmmCorePrivate->Smst->SmiManage (
&CommunicateHeader->HeaderGuid,
NULL,
CommunicateHeader->Data,
&TempCommSize
);
- TempCommSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
+ TempCommSize += CommHeaderSize;
if (CommSize != NULL) {
*CommSize = TempCommSize;
}
+ if (CommunicateHeaderV3 != NULL) {
+ CommunicateHeaderV3->BufferSize = TempCommSize;
+ }
+
//
// Restore original InSmm state
//
@@ -652,6 +708,46 @@ SmmCommunicationMmCommunicate2 (
}
/**
+ Communicates with a registered handler.
+
+ This function provides a service to send and receive messages from a registered UEFI service.
+
+ @param[in] This The EFI_MM_COMMUNICATION3_PROTOCOL instance.
+ @param[in, out] CommBufferPhysical Physical address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+ @param[in, out] CommBufferVirtual Virtual address of the MM communication buffer, of which content must
+ start with EFI_MM_COMMUNICATE_HEADER_V3.
+ @param[out] CommSize The size of data being returned. Zero if the handler does not wish to
+ reply with any data. This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS The message was successfully posted.
+ @retval EFI_INVALID_PARAMETER CommBufferPhysical was NULL or CommBufferVirtual was NULL.
+ @retval EFI_BAD_BUFFER_SIZE The buffer is too large for the MM implementation.
+ If this error is returned, the MessageLength field
+ in the CommBuffer header or the integer pointed by
+ CommSize, are updated to reflect the maximum payload
+ size the implementation can accommodate.
+ @retval EFI_ACCESS_DENIED The CommunicateBuffer parameter or CommSize parameter,
+ if not omitted, are in address range that cannot be
+ accessed by the MM environment.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicationMmCommunicate3 (
+ IN CONST EFI_MM_COMMUNICATION3_PROTOCOL *This,
+ IN OUT VOID *CommBufferPhysical,
+ IN OUT VOID *CommBufferVirtual
+ )
+{
+ return SmmCommunicationCommunicate (
+ &mSmmCommunication,
+ CommBufferPhysical,
+ NULL
+ );
+}
+
+/**
Event notification that is fired when GUIDed Event Group is signaled.
@param Event The Event that is being processed, not used.
@@ -1878,6 +1974,8 @@ SmmIplEntry (
&mSmmCommunication,
&gEfiMmCommunication2ProtocolGuid,
&mMmCommunication2,
+ &gEfiMmCommunication3ProtocolGuid,
+ &mMmCommunication3,
NULL
);
ASSERT_EFI_ERROR (Status);
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
index ddeb39c..e983bb2 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
@@ -52,6 +52,7 @@
gEfiSmmBase2ProtocolGuid ## PRODUCES
gEfiSmmCommunicationProtocolGuid ## PRODUCES
gEfiMmCommunication2ProtocolGuid ## PRODUCES
+ gEfiMmCommunication3ProtocolGuid ## PRODUCES
gEfiSmmAccess2ProtocolGuid ## CONSUMES
## NOTIFY
## CONSUMES
@@ -80,6 +81,7 @@
gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES ## SystemTable
+ gEfiMmCommunicateHeaderV3Guid ## SOMETIMES_CONSUMES ## UNDEFINED # MM communication v3
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber ## SOMETIMES_CONSUMES