From cd9bee0010348235f8e87e5ec30c6605a2f3ffd5 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Sun, 5 Oct 2025 00:31:42 -0700 Subject: [PATCH 01/36] StandaloneMmHob removed --- .../PlatformIntegrationSteps.md | 6 -- .../Drivers/StandaloneMmHob/StandaloneMmHob.c | 62 ------------------- .../StandaloneMmHob/StandaloneMmHob.inf | 45 -------------- 3 files changed, 113 deletions(-) delete mode 100644 MmSupervisorPkg/Drivers/StandaloneMmHob/StandaloneMmHob.c delete mode 100644 MmSupervisorPkg/Drivers/StandaloneMmHob/StandaloneMmHob.inf diff --git a/MmSupervisorPkg/Docs/PlatformIntegration/PlatformIntegrationSteps.md b/MmSupervisorPkg/Docs/PlatformIntegration/PlatformIntegrationSteps.md index 91e7cdfa..fee2a6ea 100644 --- a/MmSupervisorPkg/Docs/PlatformIntegration/PlatformIntegrationSteps.md +++ b/MmSupervisorPkg/Docs/PlatformIntegration/PlatformIntegrationSteps.md @@ -92,10 +92,6 @@ acquire platform-specific details. 1. [_Optional_] `gMmProtectedRegionHobGuid` - Any protected MMIO regions such as IOMMU can be described in HOBs with this GUID to prevent access from MM. -> Note that the PEI module `MmSupervisorPkg/Drivers/StandaloneMmHob` will produce `gMmCoreDataHobGuid` which is used to - hold [`MM_CORE_PRIVATE_DATA`](https://github.com/tianocore/edk2/blob/master/StandaloneMmPkg/Include/Guid/MmCoreData.h) - and `gMmCoreMmProfileGuid` which is used to hold `MM_CORE_MM_PROFILE_DATA` as defined in `MmSupervisorPkg`. - ### PPIs Required for PEI MM IPL 1. MM Access PPI (`gEfiPeiMmAccessPpiGuid`) @@ -290,7 +286,6 @@ flash drivers, SW MMI dispatcher drivers, etc. PerformanceLib|MdeModulePkg/Library/SmmPerformanceLib/StandaloneMmPerformanceLib.inf [Components.IA32] - MmSupervisorPkg/Drivers/StandaloneMmHob/StandaloneMmHob.inf MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.inf !if $(PEI_MM_IPL_ENABLED) == TRUE MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf @@ -391,7 +386,6 @@ Note: There might be other silicon specific drivers a platform will need for the ``` bash [FV.YOUR_PEI_FV] - INF MmSupervisorPkg/Drivers/StandaloneMmHob/StandaloneMmHob.inf INF MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.inf !if $(PEI_MM_IPL_ENABLED) == TRUE INF MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf diff --git a/MmSupervisorPkg/Drivers/StandaloneMmHob/StandaloneMmHob.c b/MmSupervisorPkg/Drivers/StandaloneMmHob/StandaloneMmHob.c deleted file mode 100644 index cc235fef..00000000 --- a/MmSupervisorPkg/Drivers/StandaloneMmHob/StandaloneMmHob.c +++ /dev/null @@ -1,62 +0,0 @@ -/** @file - PEI module that builds placeholder HOBs for MM usage. - - Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
- Copyright (c) Microsoft Corporation. - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -/** - The Entry Point for this PEI module. It builds placeholder HOBs for later - MM usage. - - @param[in] FileHandle Not used. - @param[in] PeiServices General purpose services available to every PEIM. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval Other Some error occurred when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -StandaloneMmHobEntry ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - MM_CORE_DATA_HOB_DATA *HobData; - MM_CORE_MM_PROFILE_DATA *HobData3; - VOID *HobProbe; - - DEBUG ((DEBUG_INFO, "%a Entry...\n", __FUNCTION__)); - - HobProbe = GetFirstGuidHob (&gMmCoreDataHobGuid); - if (HobProbe == NULL) { - // Build the dummy GUID'd HOB for MmCore, this will be populated by MM IPL - HobData = BuildGuidHob (&gMmCoreDataHobGuid, sizeof (MM_CORE_DATA_HOB_DATA)); - HobData->Address = 0; - } - - HobProbe = GetFirstGuidHob (&gMmCoreMmProfileGuid); - if (HobProbe == NULL) { - // Build the dummy GUID'd HOB for MmCore, this will be populated by MM IPL - HobData3 = BuildGuidHob (&gMmCoreMmProfileGuid, sizeof (MM_CORE_MM_PROFILE_DATA)); - ZeroMem (HobData3, sizeof (MM_CORE_MM_PROFILE_DATA)); - } - - return EFI_SUCCESS; -} diff --git a/MmSupervisorPkg/Drivers/StandaloneMmHob/StandaloneMmHob.inf b/MmSupervisorPkg/Drivers/StandaloneMmHob/StandaloneMmHob.inf deleted file mode 100644 index 8c4730af..00000000 --- a/MmSupervisorPkg/Drivers/StandaloneMmHob/StandaloneMmHob.inf +++ /dev/null @@ -1,45 +0,0 @@ -## @file -# PEI module that builds placeholder HOBs for MM usage. -# -# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
-# Copyright (c) Microsoft Corporation. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = StandaloneMmHob - FILE_GUID = 26AC2A04-BA59-4988-909E-FF553F22B5D8 - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - ENTRY_POINT = StandaloneMmHobEntry - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - StandaloneMmHob.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - StandaloneMmPkg/StandaloneMmPkg.dec - MmSupervisorPkg/MmSupervisorPkg.dec - -[LibraryClasses] - PeimEntryPoint - BaseMemoryLib - HobLib - DebugLib - -[Guids] - gMmCoreDataHobGuid ## SOMETIMES_PRODUCES - gMmCoreMmProfileGuid ## SOMETIMES_PRODUCES - -[Depex] - TRUE From 7ffc55b489d7044bb981d88b4e122d0d61105d5c Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Sun, 5 Oct 2025 00:32:20 -0700 Subject: [PATCH 02/36] handle the IPL, still more work to do --- .../MmPeiLaunchers/Common/MmIplCommon.c | 84 ++++--- .../MmPeiLaunchers/Common/MmIplCommon.h | 2 +- .../Drivers/MmPeiLaunchers/MmDxeSupport.c | 153 ++---------- .../Drivers/MmPeiLaunchers/MmDxeSupport.inf | 2 +- .../Drivers/MmPeiLaunchers/MmIplPei.c | 226 ++++++++---------- .../Drivers/MmPeiLaunchers/MmIplPei.inf | 7 +- 6 files changed, 166 insertions(+), 308 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c index 25e2f032..57a1323b 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include @@ -31,7 +31,8 @@ VOID *mMmUserCommonBuffer = NULL; VOID *mMmSupvCommonBufferPhysical = NULL; VOID *mMmUserCommonBufferPhysical = NULL; -EFI_MM_COMMUNICATE_HEADER *mCommunicateHeader = NULL; +EFI_MM_COMMUNICATE_HEADER *mCommunicateHeader = NULL; +MM_COMM_BUFFER_STATUS *mMmCommBufferStatus = NULL; /** Helper function for MM Communication protocol or PPI. @@ -119,6 +120,8 @@ SmmCommunicationCommunicateWorker ( return EFI_BAD_BUFFER_SIZE; } + DEBUG ((DEBUG_INFO, "SmmCommunicationCommunicateWorker: Using Supervisor Communicate Buffer - %p, %p, %x\n", CommunicateHeader, CommunicateBufferPhysical, TempCommSize)); + mMmCommBufferStatus->CommunicateChannel = MM_SUPERVISOR_BUFFER_T; } else { CommunicateHeader = mMmUserCommonBuffer; CommunicateBufferPhysical = mMmUserCommonBufferPhysical; @@ -131,6 +134,8 @@ SmmCommunicationCommunicateWorker ( return EFI_BAD_BUFFER_SIZE; } + mMmCommBufferStatus->CommunicateChannel = MM_USER_BUFFER_T; + DEBUG ((DEBUG_INFO, "SmmCommunicationCommunicateWorker: Using User Communicate Buffer - %p, %p, %x\n", CommunicateHeader, CommunicateBufferPhysical, TempCommSize)); } if (CommunicateHeader != CommBuffer) { @@ -143,17 +148,15 @@ SmmCommunicationCommunicateWorker ( // Standalone version will not have the scenario when communication protocol is ready but MM foundation is not set. // Thus this function should always be invoked from non-MM environment to trigger a MMI to communicate to MM core // - if (gMmCorePrivate->InMm) { - // MU_CHANGE: MM_SUPV: For MM supervisor model, we will always communicate to core through software MMI + if (mMmCommBufferStatus->IsCommBufferValid) { ASSERT (FALSE); return EFI_INVALID_PARAMETER; } // - // Put arguments for Software SMI in gMmCorePrivate + // Put arguments for Software SMI in mMmCommBufferStatus // - gMmCorePrivate->CommunicationBuffer = (UINTN)CommunicateBufferPhysical; - gMmCorePrivate->BufferSize = TempCommSize; + mMmCommBufferStatus->IsCommBufferValid = TRUE; // MU_CHANGE: Use abstracted routine to trigger MM, where PEI and DXE will invoke their own MmControl->Trigger, respectively. // @@ -165,7 +168,7 @@ SmmCommunicationCommunicateWorker ( } // MU_CHANGE Starts: Covert UINT64 to UINTN using SafeInt routine, and use them for further operations - Status = SafeUint64ToUintn (gMmCorePrivate->BufferSize, &TempCommSize); + Status = SafeUint64ToUintn (mMmCommBufferStatus->ReturnBufferSize, &TempCommSize); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_BAD_BUFFER_SIZE; @@ -186,8 +189,8 @@ SmmCommunicationCommunicateWorker ( // Convert to 32-bit Status and return // Status = EFI_SUCCESS; - if ((UINTN)gMmCorePrivate->ReturnStatus != 0) { - Status = ENCODE_ERROR ((UINTN)gMmCorePrivate->ReturnStatus); + if ((UINTN)mMmCommBufferStatus->ReturnStatus != 0) { + Status = ENCODE_ERROR ((UINTN)mMmCommBufferStatus->ReturnStatus); } return Status; @@ -261,6 +264,7 @@ InitializeCommunicationBufferFromHob ( EFI_STATUS Status; EFI_PEI_HOB_POINTERS GuidHob; MM_COMM_REGION_HOB *CommRegionHob; + MM_COMM_BUFFER *CommBuffer; if (SupvCommonRegionDesc == NULL) { DEBUG ((DEBUG_ERROR, "%a Incoming memory descriptor cannot be NULL!!!\n", __func__)); @@ -275,36 +279,42 @@ InitializeCommunicationBufferFromHob ( } Status = EFI_SUCCESS; - while (GuidHob.Guid != NULL) { - CommRegionHob = GET_GUID_HOB_DATA (GuidHob.Guid); - if (CommRegionHob->MmCommonRegionType == MM_USER_BUFFER_T) { - if ((mMmUserCommonBufferPages != 0) || (mMmUserCommonBuffer != NULL)) { - Status = EFI_ALREADY_STARTED; - break; - } + CommRegionHob = GET_GUID_HOB_DATA (GuidHob.Guid); + if (CommRegionHob->MmCommonRegionType == MM_SUPERVISOR_BUFFER_T) { + if ((mMmSupvCommonBufferPages != 0) || (mMmSupvCommonBuffer != NULL)) { + Status = EFI_ALREADY_STARTED; + } - mMmUserCommonBufferPages = CommRegionHob->MmCommonRegionPages; - mMmUserCommonBuffer = (VOID *)(UINTN)CommRegionHob->MmCommonRegionAddr; - mMmUserCommonBufferPhysical = mMmUserCommonBuffer; - } else if (CommRegionHob->MmCommonRegionType == MM_SUPERVISOR_BUFFER_T) { - if ((mMmSupvCommonBufferPages != 0) || (mMmSupvCommonBuffer != NULL)) { - Status = EFI_ALREADY_STARTED; - break; - } + mMmSupvCommonBufferPages = CommRegionHob->MmCommonRegionPages; + mMmSupvCommonBuffer = (VOID *)(UINTN)CommRegionHob->MmCommonRegionAddr; + mMmSupvCommonBufferPhysical = mMmSupvCommonBuffer; - mMmSupvCommonBufferPages = CommRegionHob->MmCommonRegionPages; - mMmSupvCommonBuffer = (VOID *)(UINTN)CommRegionHob->MmCommonRegionAddr; - mMmSupvCommonBufferPhysical = mMmSupvCommonBuffer; + SupvCommonRegionDesc->Type = EfiRuntimeServicesData; + SupvCommonRegionDesc->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)mMmSupvCommonBuffer; + SupvCommonRegionDesc->VirtualStart = (EFI_PHYSICAL_ADDRESS)(UINTN)mMmSupvCommonBuffer; + SupvCommonRegionDesc->NumberOfPages = mMmSupvCommonBufferPages; + SupvCommonRegionDesc->Attribute = 0; + } else { + DEBUG ((DEBUG_ERROR, "%a - Invalid common buffer type %x." + "Please make sure the user buffer is published through gMmCommBufferHobGuid!!\n", __func__, CommRegionHob->MmCommonRegionType)); + Status = EFI_UNSUPPORTED; + } - SupvCommonRegionDesc->Type = EfiRuntimeServicesData; - SupvCommonRegionDesc->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)mMmSupvCommonBuffer; - SupvCommonRegionDesc->VirtualStart = (EFI_PHYSICAL_ADDRESS)(UINTN)mMmSupvCommonBuffer; - SupvCommonRegionDesc->NumberOfPages = mMmSupvCommonBufferPages; - SupvCommonRegionDesc->Attribute = 0; + // Cover the user level buffer, through the EDK2 way... + if ((mMmUserCommonBufferPages == 0) && (mMmUserCommonBuffer == NULL)) { + GuidHob.Guid = GetFirstGuidHob (&gMmCommBufferHobGuid); + if (GuidHob.Guid == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to find MM Communication Buffer HOB\n")); + DEBUG ((DEBUG_ERROR, "Only Root MMI Handlers will be supported!\n")); + return Status; } - - GuidHob.Guid = GET_NEXT_HOB (GuidHob); - GuidHob.Guid = GetNextGuidHob (&gMmCommonRegionHobGuid, GuidHob.Guid); + CommBuffer = (MM_COMM_BUFFER *)GET_GUID_HOB_DATA (GuidHob.Guid); + mMmUserCommonBufferPages = CommBuffer->NumberOfPages; + mMmUserCommonBuffer = (VOID *)(UINTN)CommBuffer->PhysicalStart; + mMmUserCommonBufferPhysical = mMmUserCommonBuffer; + mMmCommBufferStatus = (MM_COMM_BUFFER_STATUS*)(UINTN)CommBuffer->Status; + } else { + Status = EFI_ALREADY_STARTED; } if (EFI_ERROR (Status)) { @@ -360,7 +370,7 @@ QuerySupervisorVersion ( ZeroMem ((VOID *)(UINTN)mCommunicateHeader, Size); CopyGuid (&(mCommunicateHeader->HeaderGuid), &gMmSupervisorRequestHandlerGuid); - mCommunicateHeader->MessageLength = sizeof (MM_SUPERVISOR_REQUEST_HEADER); + mCommunicateHeader->MessageLength = sizeof (MM_SUPERVISOR_REQUEST_HEADER) + sizeof (MM_SUPERVISOR_VERSION_INFO_BUFFER); RequestHeader = (MM_SUPERVISOR_REQUEST_HEADER *)mCommunicateHeader->Data; RequestHeader->Signature = MM_SUPERVISOR_REQUEST_SIG; diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.h b/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.h index ae4db334..e3a89a33 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.h +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.h @@ -127,6 +127,6 @@ extern VOID *mMmSupvCommonBufferPhysical; extern VOID *mMmUserCommonBufferPhysical; extern EFI_MM_COMMUNICATE_HEADER *mCommunicateHeader; -extern MM_CORE_PRIVATE_DATA *gMmCorePrivate; +extern MM_COMM_BUFFER_STATUS *mMmCommBufferStatus; #endif // MM_IPL_COMMON_H_ diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c index c91aebee..8f7e0557 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include // MU_CHANGE: MM_SUPV: Added MM Supervisor request data structure @@ -38,42 +38,6 @@ // Function prototypes from produced protocols // -/** - Indicate whether the driver is currently executing in the SMM Initialization phase. - - @param This The EFI_MM_BASE_PROTOCOL instance. - @param InSmram Pointer to a Boolean which, on return, indicates that the driver is currently executing - inside of SMRAM (TRUE) or outside of SMRAM (FALSE). - - @retval EFI_INVALID_PARAMETER InSmram was NULL. - @retval EFI_SUCCESS The call returned successfully. - -**/ -EFI_STATUS -EFIAPI -SmmBase2InSmram ( - IN CONST EFI_MM_BASE_PROTOCOL *This, - OUT BOOLEAN *InSmram - ); - -/** - Retrieves the location of the System Management System Table (Mmst). - - @param This The EFI_MM_BASE_PROTOCOL instance. - @param Mmst On return, points to a pointer to the System Management Service Table (MMST). - - @retval EFI_INVALID_PARAMETER Mmst or This was invalid. - @retval EFI_SUCCESS The memory was returned to the system. - @retval EFI_UNSUPPORTED Not in SMM. - -**/ -EFI_STATUS -EFIAPI -SmmBase2GetSmstLocation ( - IN CONST EFI_MM_BASE_PROTOCOL *This, - OUT EFI_MM_SYSTEM_TABLE **Mmst - ); - /** Communicates with a registered handler. @@ -256,14 +220,6 @@ typedef struct { // EFI_HANDLE mSmmIplHandle = NULL; -// -// SMM Base 2 Protocol instance -// -EFI_MM_BASE_PROTOCOL mSmmBase2 = { - SmmBase2InSmram, - SmmBase2GetSmstLocation -}; - // // SMM Communication Protocol instance // @@ -288,12 +244,6 @@ MM_SUPERVISOR_COMMUNICATION_PROTOCOL mMmSupvCommunication = { .Communicate = SupvCommunicationCommunicate }; -// MU_CHANGE: MM_SUPV: Designated a pointer for core private data as it is allocated runtime -// -// Global pointer used to access mSmmCorePrivateData from outside and inside SMM -// -MM_CORE_PRIVATE_DATA *gMmCorePrivate = NULL; - // // SMM IPL global variables // @@ -342,7 +292,7 @@ SMM_IPL_EVENT_NOTIFICATION mSmmIplEvents[] = { // { FALSE, FALSE, &gEfiEventReadyToBootGuid, SmmIplGuidedEventNotify, &gEfiEventReadyToBootGuid, TPL_CALLBACK, NULL }, // - // Declare event notification on SetVirtualAddressMap() Event Group. This is used to convert gMmCorePrivate + // Declare event notification on SetVirtualAddressMap() Event Group. This is used to convert mMmCommBufferStatus // and mSmmControl2 from physical addresses to virtual addresses. // { FALSE, FALSE, &gEfiEventVirtualAddressChangeGuid, SmmIplSetVirtualAddressNotify, NULL, TPL_CALLBACK, NULL }, @@ -370,64 +320,6 @@ InternalMmControlTrigger ( return mSmmControl2->Trigger (mSmmControl2, NULL, NULL, FALSE, 0); } -/** - Indicate whether the driver is currently executing in the SMM Initialization phase. - - @param This The EFI_MM_BASE_PROTOCOL instance. - @param InSmram Pointer to a Boolean which, on return, indicates that the driver is currently executing - inside of SMRAM (TRUE) or outside of SMRAM (FALSE). - - @retval EFI_INVALID_PARAMETER InSmram was NULL. - @retval EFI_SUCCESS The call returned successfully. - -**/ -EFI_STATUS -EFIAPI -SmmBase2InSmram ( - IN CONST EFI_MM_BASE_PROTOCOL *This, - OUT BOOLEAN *InSmram - ) -{ - if (InSmram == NULL) { - return EFI_INVALID_PARAMETER; - } - - *InSmram = gMmCorePrivate->InMm; - - return EFI_SUCCESS; -} - -/** - Retrieves the location of the System Management System Table (SMST). - - @param This The EFI_MM_BASE_PROTOCOL instance. - @param Smst On return, points to a pointer to the System Management Service Table (SMST). - - @retval EFI_INVALID_PARAMETER Smst or This was invalid. - @retval EFI_SUCCESS The memory was returned to the system. - @retval EFI_UNSUPPORTED Not in SMM. - -**/ -EFI_STATUS -EFIAPI -SmmBase2GetSmstLocation ( - IN CONST EFI_MM_BASE_PROTOCOL *This, - OUT EFI_MM_SYSTEM_TABLE **Mmst - ) -{ - if ((This == NULL) || (Mmst == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (!gMmCorePrivate->InMm) { - return EFI_UNSUPPORTED; - } - - *Mmst = (EFI_MM_SYSTEM_TABLE *)(UINTN)gMmCorePrivate->Mmst; - - return EFI_SUCCESS; -} - // MU_CHANGE: MM_SUPV: Added interface for MM Supervisor communication /** @@ -708,7 +600,7 @@ SmmIplSetVirtualAddressNotify ( // MU_CHANGE: These "external "entries need update since used in MM Communication routine EfiConvertPointer (0x0, (VOID **)&mMmSupvCommonBuffer); EfiConvertPointer (0x0, (VOID **)&mMmUserCommonBuffer); - EfiConvertPointer (0x0, (VOID **)&gMmCorePrivate); + EfiConvertPointer (0x0, (VOID **)&mMmCommBufferStatus); EfiConvertPointer (0x0, (VOID **)&mMmSupvCommunication.CommunicationRegion.VirtualStart); } @@ -738,7 +630,7 @@ UpdateDxeCommunicateBuffer ( MM_SUPERVISOR_COMM_UPDATE_BUFFER *NewCommBuffer; VOID *NewUserCommBuffer; VOID *NewSupvCommBuffer; - VOID *NewMmCoreBuffer; + VOID *NewMmCommBufferStatus; if ((VersionInfo == NULL) || (UpdatedCommBuffer == NULL)) { ASSERT (VersionInfo != NULL); @@ -754,12 +646,12 @@ UpdateDxeCommunicateBuffer ( // Now we are in the real deal, start with allocating new buffers NewUserCommBuffer = AllocateAlignedRuntimePages (mMmUserCommonBufferPages, EFI_PAGE_SIZE); NewSupvCommBuffer = AllocateAlignedRuntimePages (mMmSupvCommonBufferPages, EFI_PAGE_SIZE); - NewMmCoreBuffer = AllocateAlignedRuntimePages (EFI_SIZE_TO_PAGES (sizeof (MM_CORE_PRIVATE_DATA)), EFI_PAGE_SIZE); + NewMmCommBufferStatus = AllocateAlignedRuntimePages (EFI_SIZE_TO_PAGES (sizeof (MM_COMM_BUFFER_STATUS)), EFI_PAGE_SIZE); - if ((NewUserCommBuffer == NULL) || (NewSupvCommBuffer == NULL) || (NewMmCoreBuffer == NULL)) { + if ((NewUserCommBuffer == NULL) || (NewSupvCommBuffer == NULL) || (NewMmCommBufferStatus == NULL)) { ASSERT (NewUserCommBuffer != NULL); ASSERT (NewSupvCommBuffer != NULL); - ASSERT (NewMmCoreBuffer != NULL); + ASSERT (NewMmCommBufferStatus != NULL); return EFI_OUT_OF_RESOURCES; } @@ -774,7 +666,8 @@ UpdateDxeCommunicateBuffer ( ZeroMem ((VOID *)(UINTN)mCommunicateHeader, Size); CopyGuid (&(mCommunicateHeader->HeaderGuid), &gMmSupervisorRequestHandlerGuid); - mCommunicateHeader->MessageLength = sizeof (MM_SUPERVISOR_REQUEST_HEADER); + mCommunicateHeader->MessageLength = sizeof (MM_SUPERVISOR_REQUEST_HEADER) + + sizeof (MM_SUPERVISOR_COMM_UPDATE_BUFFER); RequestHeader = (MM_SUPERVISOR_REQUEST_HEADER *)mCommunicateHeader->Data; RequestHeader->Signature = MM_SUPERVISOR_REQUEST_SIG; @@ -785,9 +678,9 @@ UpdateDxeCommunicateBuffer ( CopyMem (&(NewCommBuffer->NewMmCoreData.IdentifierGuid), &gEfiCallerIdGuid, sizeof (EFI_GUID)); NewCommBuffer->NewMmCoreData.MemoryDescriptor.Attribute = EFI_MEMORY_XP | EFI_MEMORY_SP; NewCommBuffer->NewMmCoreData.MemoryDescriptor.Type = EfiRuntimeServicesData; - NewCommBuffer->NewMmCoreData.MemoryDescriptor.NumberOfPages = EFI_SIZE_TO_PAGES ((sizeof (MM_CORE_PRIVATE_DATA) + EFI_PAGE_MASK) & ~(EFI_PAGE_MASK)); - NewCommBuffer->NewMmCoreData.MemoryDescriptor.PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)NewMmCoreBuffer; - NewCommBuffer->NewMmCoreData.MemoryDescriptor.VirtualStart = (EFI_PHYSICAL_ADDRESS)(UINTN)NewMmCoreBuffer; + NewCommBuffer->NewMmCoreData.MemoryDescriptor.NumberOfPages = EFI_SIZE_TO_PAGES ((sizeof (MM_COMM_BUFFER_STATUS) + EFI_PAGE_MASK) & ~(EFI_PAGE_MASK)); + NewCommBuffer->NewMmCoreData.MemoryDescriptor.PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)NewMmCommBufferStatus; + NewCommBuffer->NewMmCoreData.MemoryDescriptor.VirtualStart = (EFI_PHYSICAL_ADDRESS)(UINTN)NewMmCommBufferStatus; CopyMem (&(NewCommBuffer->NewCommBuffers[MM_SUPERVISOR_BUFFER_T].IdentifierGuid), &gEfiCallerIdGuid, sizeof (EFI_GUID)); NewCommBuffer->NewCommBuffers[MM_SUPERVISOR_BUFFER_T].MemoryDescriptor.Attribute = EFI_MEMORY_XP | EFI_MEMORY_SP; @@ -814,9 +707,10 @@ UpdateDxeCommunicateBuffer ( } // Re-check the return status on the new buffers. - gMmCorePrivate = (MM_CORE_PRIVATE_DATA *)NewMmCoreBuffer; - if ((UINTN)gMmCorePrivate->ReturnStatus != 0) { - Status = gMmCorePrivate->ReturnStatus; + mMmCommBufferStatus = (MM_COMM_BUFFER_STATUS *)NewMmCommBufferStatus; + DEBUG ((DEBUG_ERROR, "%a - Updated mMmCommMailboxBufferStatus to new location - %p!\n", __func__, mMmCommBufferStatus)); + if ((UINTN)mMmCommBufferStatus->ReturnStatus != 0) { + Status = mMmCommBufferStatus->ReturnStatus; DEBUG ((DEBUG_ERROR, "%a Failed to communicate to MM to switch core mailbox - %r!!\n", __FUNCTION__, Status)); Status = EFI_DEVICE_ERROR; goto Done; @@ -1011,8 +905,6 @@ MmDxeSupportEntry ( EFI_STATUS Status; UINTN Index; VOID *Registration; - MM_CORE_DATA_HOB_DATA *DataInHob; - EFI_PEI_HOB_POINTERS HobPointer; // MU_CHANGE: MM_SUPV: Test supervisor communication before publishing protocol MM_SUPERVISOR_VERSION_INFO_BUFFER VersionInfo; MM_SUPERVISOR_COMM_UPDATE_BUFFER NewCommBuffer; @@ -1026,16 +918,6 @@ MmDxeSupportEntry ( return Status; } - // MU_CHANGE: Fetch allocated gMmCorePrivate address from HOB data - // Here we allocate the core private data and copy the data - HobPointer.Guid = GetFirstGuidHob (&gMmCoreDataHobGuid); - if (HobPointer.Guid == NULL) { - return EFI_DEVICE_ERROR; - } - - DataInHob = GET_GUID_HOB_DATA (HobPointer.Guid); - gMmCorePrivate = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address; - // // Get SMM Control2 Protocol // @@ -1060,6 +942,7 @@ MmDxeSupportEntry ( return Status; } + // Needs clean up Status = PublishMmCommunicationBuffer (&NewCommBuffer); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a Failed to publish communicate buffer configuration tables - %r\n", __FUNCTION__, Status)); @@ -1080,8 +963,6 @@ MmDxeSupportEntry ( // Status = gBS->InstallMultipleProtocolInterfaces ( &mSmmIplHandle, - &gEfiSmmBase2ProtocolGuid, - &mSmmBase2, &gEfiSmmCommunicationProtocolGuid, &mSmmCommunication, &gEfiMmCommunication2ProtocolGuid, diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf index 40658d94..a3fd91d0 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf @@ -70,11 +70,11 @@ gEfiEventReadyToBootGuid gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event - gMmCoreDataHobGuid ## CONSUMES gMmCommonRegionHobGuid ## CONSUMES gMmSupervisorRequestHandlerGuid ## CONSUMES gMmSupervisorCommunicationRegionTableGuid ## CONSUMES gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES + gMmCommBufferHobGuid ## CONSUMES [Depex] gEfiSmmControl2ProtocolGuid diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index 51ca3b07..ca618c2d 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -18,8 +18,7 @@ #include #include // MU_CHANGE: Added MM configuration PPI -#include -#include +#include #include #include #include @@ -77,11 +76,6 @@ SmmCommunicationCommunicate ( IN OUT UINTN *CommSize ); -EFI_MMRAM_DESCRIPTOR * -GetFullMmramRanges ( - OUT UINTN *FullMmramRangeCount - ); - // MU_CHANGE: MM_SUPV: Supervisor communication function prototype /** @@ -158,28 +152,6 @@ STATIC EFI_PEI_PPI_DESCRIPTOR mPeiMmIplPpiList[] = } }; -// -// SMM Core Private Data structure that contains the data shared between -// the SMM IPL and the SMM Core. -// -MM_CORE_PRIVATE_DATA mSmmCorePrivateData = { - MM_CORE_PRIVATE_DATA_SIGNATURE, // Signature - 0, // MmramRangeCount - 0, // MmramRanges - 0, // MmEntryPoint - FALSE, // MmEntryPointRegistered - FALSE, // InMm - 0, // Mmst - 0, // CommunicationBuffer - 0, // BufferSize - EFI_SUCCESS // ReturnStatus -}; - -// -// Global pointer used to access mSmmCorePrivateData from outside and inside SMM -// -MM_CORE_PRIVATE_DATA *gMmCorePrivate = NULL; - // // SMM IPL global variables // @@ -237,6 +209,8 @@ InternalMmControlTrigger ( VOID GetMmramCacheRange ( IN EFI_MMRAM_DESCRIPTOR *MmramRange, + IN EFI_MMRAM_DESCRIPTOR *MmramRanges, + IN UINTN MmramRangeCount, OUT EFI_PHYSICAL_ADDRESS *MmramCacheBase, OUT UINT64 *MmramCacheSize ) @@ -245,16 +219,13 @@ GetMmramCacheRange ( EFI_PHYSICAL_ADDRESS RangeCpuStart; UINT64 RangePhysicalSize; BOOLEAN FoundAdjacentRange; - EFI_MMRAM_DESCRIPTOR *MmramRanges; *MmramCacheBase = MmramRange->CpuStart; *MmramCacheSize = MmramRange->PhysicalSize; - MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRanges; - do { FoundAdjacentRange = FALSE; - for (Index = 0; (UINT64)Index < gMmCorePrivate->MmramRangeCount; Index++) { + for (Index = 0; (UINT64)Index < MmramRangeCount; Index++) { RangeCpuStart = MmramRanges[Index].CpuStart; RangePhysicalSize = MmramRanges[Index].PhysicalSize; if ((RangeCpuStart < *MmramCacheBase) && (*MmramCacheBase == (RangeCpuStart + RangePhysicalSize))) { @@ -384,7 +355,9 @@ SmmIplGuidedEventNotify ( } // MU_CHANGE Starts: MM_SUPV: Will immediately signal MM core to dispatch MM drivers - +#define COMM_BUFFER_MM_DISPATCH_ERROR 0x00 +#define COMM_BUFFER_MM_DISPATCH_SUCCESS 0x01 +#define COMM_BUFFER_MM_DISPATCH_RESTART 0x02 /** Invokes the MM core to dispatch drivers from inside MM environment. This function will only be called after MM foundation is successfully set. @@ -428,6 +401,8 @@ MmDriverDispatchNotify ( // if (mCommunicateHeader->Data[0] != COMM_BUFFER_MM_DISPATCH_RESTART) { return Status; + } else { + ASSERT (FALSE); } } @@ -724,12 +699,65 @@ MmIplAllocateMmramPage ( // ZeroMem (&MmramInfoHob->Name, sizeof (MmramInfoHob->Name)); - // Update the gMmCorePrivate MmRanges to point to the new new version of mmRanges - gMmCorePrivate->MmramRanges = (EFI_PHYSICAL_ADDRESS)(UINTN)GetFullMmramRanges ((UINTN *)&gMmCorePrivate->MmramRangeCount); - return Allocated->CpuStart; } +/** + Builds a HOB for a loaded PE32 module. + + This function builds a HOB for a loaded PE32 module. + It can only be invoked during PEI phase; + If physical address of the Module is not 4K aligned, then ASSERT(). + If new HOB buffer is NULL, then ASSERT(). + + @param[in] Hob The pointer of new HOB buffer. + @param[in, out] HobBufferSize The available size of the HOB buffer when as input. + The used size of when as output. + @param[in] ModuleName The GUID File Name of the module. + @param[in] Base The 64 bit physical address of the module. + @param[in] Length The length of the module in bytes. + @param[in] EntryPoint The 64 bit physical address of the module entry point. + +**/ +EFI_STATUS +MmIplBuildMmCoreAllocationHob ( + IN CONST EFI_GUID *ModuleName, + IN EFI_PHYSICAL_ADDRESS Base, + IN UINT64 Length, + IN EFI_PHYSICAL_ADDRESS EntryPoint + ) +{ + EFI_STATUS Status; + + if (!IS_ALIGNED (Base, EFI_PAGE_SIZE) || !IS_ALIGNED (Length, EFI_PAGE_SIZE)) { + Status = EFI_INVALID_PARAMETER; + goto Exit; + } + + if ((EntryPoint < Base) || (EntryPoint >= Base + Length)) { + Status = EFI_INVALID_PARAMETER; + goto Exit; + } + + // TODO: This deviates from the EDK2 implementation which uses + // the build module HOB. + BuildMemoryAllocationHob ( + Base, + Length, + EfiReservedMemoryType + ); + + TagMemoryAllocationHobWithGuid ( + Base, + ModuleName + ); + + Status = EFI_SUCCESS; + +Exit: + return Status; +} + // MU_CHANGE Ends /** @@ -740,16 +768,13 @@ MmIplAllocateMmramPage ( hold SMM Core will be excluded. @param[in, out] MmramRangeSmmCore Descriptor for the range of SMRAM to hold SMM Core. - @param[in] Context Context to pass into SMM Core - @return EFI_STATUS **/ EFI_STATUS ExecuteMmCoreFromMmram ( IN OUT EFI_MMRAM_DESCRIPTOR *MmramRange, - IN OUT EFI_MMRAM_DESCRIPTOR *MmramRangeSmmCore, - IN VOID *Context + IN OUT EFI_MMRAM_DESCRIPTOR *MmramRangeSmmCore ) { EFI_STATUS Status; @@ -757,10 +782,7 @@ ExecuteMmCoreFromMmram ( PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; UINTN PageCount; STANDALONE_MM_FOUNDATION_ENTRY_POINT EntryPoint; - EFI_HOB_GUID_TYPE *GuidHob; - MM_CORE_DATA_HOB_DATA *DataInHob; - // MM_CORE_MM_PROFILE_DATA *BufferInHob; - VOID *HobStart; + VOID *HobStart; DEBUG ((DEBUG_INFO, "%a Enters...\n", __func__)); // @@ -838,20 +860,20 @@ ExecuteMmCoreFromMmram ( // DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.EntryPoint)); - gMmCorePrivate->MmCoreImageBase = ImageContext.ImageAddress; - gMmCorePrivate->MmCoreImageSize = ImageContext.ImageSize; - gMmCorePrivate->MmCoreEntryPoint = ImageContext.EntryPoint; - DEBUG ((DEBUG_INFO, "PiSmmCoreImageBase - 0x%016lx\n", gMmCorePrivate->MmCoreImageBase)); - DEBUG ((DEBUG_INFO, "PiSmmCoreImageSize - 0x%016lx\n", gMmCorePrivate->MmCoreImageSize)); - DEBUG ((DEBUG_INFO, "PiSmmCoreEntryPont - 0x%016lx\n", gMmCorePrivate->MmCoreEntryPoint)); - - // MU_CHANGE: Patch the core private data allocated in this module into HOB - GuidHob = GetFirstGuidHob (&gMmCoreDataHobGuid); - DataInHob = GET_GUID_HOB_DATA (GuidHob); - DataInHob->Address = (UINTN)gMmCorePrivate; - // MU_CHANGE Starts: To load x64 MM foundation, mode switch is needed EntryPoint = (STANDALONE_MM_FOUNDATION_ENTRY_POINT)(UINTN)ImageContext.EntryPoint; + + Status = MmIplBuildMmCoreAllocationHob ( + &gMmSupervisorCoreGuid, + ImageContext.ImageAddress, + (UINT64)EFI_PAGES_TO_SIZE (PageCount), + (EFI_PHYSICAL_ADDRESS)(UINTN)ImageContext.EntryPoint + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a Failed to build MM core module HOB - %r...\n", __func__, Status)); + goto Exit; + } + HobStart = GetHobList (); #ifdef MDE_CPU_IA32 // @@ -1112,65 +1134,6 @@ SmmIsMmramOverlap ( return FALSE; } -/** - Get full SMRAM ranges. - - It will get SMRAM ranges from either the gEfiMmPeiMmramMemoryReserveGuid or - gEfiSmmSmramMemoryGuid HOB. - - @param[out] FullMmramRangeCount Output pointer to full SMRAM range count. - - @return Pointer to full SMRAM ranges. - -**/ -EFI_MMRAM_DESCRIPTOR * -GetFullMmramRanges ( - OUT UINTN *FullMmramRangeCount - ) -{ - EFI_MMRAM_DESCRIPTOR *FullMmramRanges; - UINTN MmramRangeCount; - EFI_MMRAM_DESCRIPTOR *MmramRanges; - - EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData; - EFI_HOB_GUID_TYPE *MmramRangesHob; - - MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid); - if (MmramRangesHob == NULL) { - MmramRangesHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid); - if (MmramRangesHob == NULL) { - DEBUG ((DEBUG_ERROR, "[%a] - Critical HOB missing that describes MMRAM regions. Cannot load MM.\n", __FUNCTION__)); - ASSERT (MmramRangesHob != NULL); - PANIC ("Critical HOB missing that describes MMRAM regions"); - } - } - - MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); - if (MmramRangesHobData == NULL) { - return NULL; - } - - MmramRanges = MmramRangesHobData->Descriptor; - if (MmramRanges == NULL) { - return NULL; - } - - MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions; - if (MmramRanges == NULL) { - return NULL; - } - - FullMmramRanges = (EFI_MMRAM_DESCRIPTOR *)AllocateZeroPool (MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR)); - if (FullMmramRanges == NULL) { - return NULL; - } - - CopyMem (FullMmramRanges, MmramRanges, (MmramRangeCount) * sizeof (EFI_MMRAM_DESCRIPTOR)); - *FullMmramRangeCount = MmramRangeCount; - - return FullMmramRanges; -} - /** The Entry Point for PEI MM IPL @@ -1222,12 +1185,6 @@ MmIplPeiEntry ( return Status; } - // MU_CHANGE: MM_SUPV: Allocate designated runtime buffer for gMmCorePrivate, it will be unblocked with Supervisor access - // Here we allocate the core private data and copy the data - gMmCorePrivate = AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof (MM_CORE_PRIVATE_DATA)), SIZE_4KB); - ASSERT (gMmCorePrivate != NULL); - CopyMem (gMmCorePrivate, &mSmmCorePrivateData, sizeof (MM_CORE_PRIVATE_DATA)); - // // Get SMM Access PPI // @@ -1252,9 +1209,6 @@ MmIplPeiEntry ( ); ASSERT_EFI_ERROR (Status); - gMmCorePrivate->MmramRanges = (EFI_PHYSICAL_ADDRESS)(UINTN)GetFullMmramRanges ((UINTN *)&gMmCorePrivate->MmramRangeCount); - MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRanges; - // // Open all SMRAM ranges // @@ -1267,6 +1221,19 @@ MmIplPeiEntry ( return EFI_DEVICE_ERROR; } + MmramRanges = AllocatePool (Size); + if (MmramRanges == NULL) { + ASSERT (MmramRanges != NULL); + return EFI_OUT_OF_RESOURCES; + } + + Status = mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, &Size, MmramRanges); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SMM IPL failed to get SMRAM capabilities - %r\n", Status)); + ASSERT (FALSE); + return Status; + } + MmramRangeCount = Size / sizeof (EFI_MMRAM_DESCRIPTOR); for (Index = 0; Index < MmramRangeCount; Index++) { Status = mSmmAccess->Open ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); @@ -1288,7 +1255,7 @@ MmIplPeiEntry ( // Find the largest SMRAM range between 1MB and 4GB that is at least 256KB - 4K in size // mCurrentMmramRange = NULL; - for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; (UINT64)Index < gMmCorePrivate->MmramRangeCount; Index++) { + for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; (UINT64)Index < MmramRangeCount; Index++) { // // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization // @@ -1317,7 +1284,7 @@ MmIplPeiEntry ( (VOID *)(UINTN)(mCurrentMmramRange->CpuStart + mCurrentMmramRange->PhysicalSize - 1) )); - GetMmramCacheRange (mCurrentMmramRange, &mMmramCacheBase, &mMmramCacheSize); + GetMmramCacheRange (mCurrentMmramRange, MmramRanges, MmramRangeCount, &mMmramCacheBase, &mMmramCacheSize); // MU_CHANGE: MM_SUPV: Memory space descriptor marking is directly using MTRR registers // // Make sure we can change the desired memory attributes. @@ -1338,8 +1305,7 @@ MmIplPeiEntry ( // Status = ExecuteMmCoreFromMmram ( mCurrentMmramRange, - &MmramRanges[gMmCorePrivate->MmramRangeCount - 1], - gMmCorePrivate + &MmramRanges[MmramRangeCount - 1] ); if (EFI_ERROR (Status)) { // @@ -1435,7 +1401,7 @@ MmIplPeiEntry ( // // Free all allocated resources // - FreePool ((VOID *)(UINTN)gMmCorePrivate->MmramRanges); + FreePool ((VOID *)MmramRanges); return EFI_UNSUPPORTED; } diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf index f9d0ea49..a7746d76 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf @@ -75,13 +75,14 @@ [Guids] # gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported - gMmCoreDataHobGuid ## CONSUMES gMmCoreMmProfileGuid ## SOMETIMES_CONSUMES gMmCommonRegionHobGuid ## PRODUCES gMmSupervisorDriverDispatchGuid ## PRODUCES ## Invoke driver dispatcher gMmSupervisorRequestHandlerGuid ## CONSUMES - gEfiMmPeiMmramMemoryReserveGuid - gEfiSmmSmramMemoryGuid + gEfiMmPeiMmramMemoryReserveGuid ## CONSUMES + gEfiSmmSmramMemoryGuid ## CONSUMES + gMmCommBufferHobGuid ## CONSUMES + gMmSupervisorCoreGuid ## CONSUMES [Pcd] # gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported From 07917f5515ee74b91603591ff06d49773c553ef5 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Sun, 5 Oct 2025 00:32:56 -0700 Subject: [PATCH 03/36] handle the MM comm buffer prep --- .../MmCommunicationBufferPei.c | 96 +++++++++++++++++-- .../MmCommunicationBufferPei.inf | 1 + 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.c b/MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.c index 836bd673..3d1aae82 100644 --- a/MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.c +++ b/MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.c @@ -22,6 +22,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include +#include #include EFI_PEI_PPI_DESCRIPTOR MmCommunicationBuffPpi = { @@ -46,8 +47,7 @@ EFI_PEI_PPI_DESCRIPTOR MmCommunicationBuffPpi = { **/ STATIC EFI_STATUS -ReserveCommBuffer ( - IN UINT64 Type, +ReserveSupvCommBuffer ( IN UINT64 PageSize, OUT EFI_PHYSICAL_ADDRESS *BufferAddress OPTIONAL ) @@ -55,8 +55,8 @@ ReserveCommBuffer ( EFI_STATUS Status; MM_COMM_REGION_HOB *CommRegionHob; - if ((Type >= MM_OPEN_BUFFER_CNT) || (PageSize == 0)) { - DEBUG ((DEBUG_ERROR, "%a Invalid input Type 0x%x or PageSize 0x%x!\n", __FUNCTION__, Type, PageSize)); + if (PageSize == 0) { + DEBUG ((DEBUG_ERROR, "%a Invalid input PageSize 0x%x!\n", __FUNCTION__, PageSize)); ASSERT (FALSE); Status = EFI_INVALID_PARAMETER; goto Done; @@ -75,7 +75,7 @@ ReserveCommBuffer ( } ZeroMem (CommRegionHob, sizeof (MM_COMM_REGION_HOB)); - CommRegionHob->MmCommonRegionType = Type; + CommRegionHob->MmCommonRegionType = MM_SUPERVISOR_BUFFER_T; // // Allocate and fill CommRegionHob @@ -104,6 +104,88 @@ ReserveCommBuffer ( return Status; } +/** + Helper function to allocate reserved buffer for communication buffer based on + given buffer type and size. + + @param[in] PageSize Number of pages needs to be allocated for given type. + @param[out] BufferAddress Buffer address allocated for given type when operation + returns successfully. Otherwise it will be set to NULL. + + @retval EFI_SUCCESS The routine completes successfully. + @retval EFI_INVALID_PARAMETER The input type is not supported or page size is invalid. + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create communication buffer. +**/ +STATIC +EFI_STATUS +ReserveUserCommBuffer ( + IN UINT64 PageSize, + OUT EFI_PHYSICAL_ADDRESS *BufferAddress OPTIONAL + ) +{ + EFI_STATUS Status; + MM_COMM_BUFFER *CommRegionHob; + MM_COMM_BUFFER_STATUS *CommRegionStatus; + + if (PageSize == 0) { + DEBUG ((DEBUG_ERROR, "%a Invalid input PageSize 0x%x!\n", __FUNCTION__, PageSize)); + ASSERT (FALSE); + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + if (BufferAddress != NULL) { + *BufferAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)NULL; + } + + CommRegionHob = BuildGuidHob (&gMmCommBufferHobGuid, sizeof (MM_COMM_BUFFER)); + if (CommRegionHob == NULL) { + DEBUG ((DEBUG_ERROR, "%a Failed to create GUIDed HOB %g!\n", __FUNCTION__, &gMmCommBufferHobGuid)); + ASSERT (FALSE); + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + ZeroMem (CommRegionHob, sizeof (MM_COMM_BUFFER)); + + // + // Allocate and fill CommRegionHob + // + CommRegionHob->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePages ((UINTN)PageSize); + if (NULL == (VOID *)(UINTN)CommRegionHob->PhysicalStart) { + DEBUG ((DEBUG_ERROR, "%a Request of allocating common buffer of 0x%x pages failed!\n", __FUNCTION__, PageSize)); + ASSERT (FALSE); + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + CommRegionHob->NumberOfPages = PageSize; + + CommRegionStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (MM_COMM_BUFFER_STATUS))); + if (NULL == (VOID *)CommRegionStatus) { + DEBUG ((DEBUG_ERROR, "%a Request of allocating common buffer status failed!\n", __FUNCTION__)); + ASSERT (FALSE); + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + ZeroMem (CommRegionStatus, sizeof (MM_COMM_BUFFER_STATUS)); + CommRegionHob->Status = (EFI_PHYSICAL_ADDRESS)(UINTN)CommRegionStatus; + + DEBUG ((DEBUG_INFO, "Reserved MM common buffer for user\n")); + DEBUG ((DEBUG_INFO, " PhysicalStart - 0x%lx\n", CommRegionHob->PhysicalStart)); + DEBUG ((DEBUG_INFO, " NumberOfPages - 0x%lx\n", CommRegionHob->NumberOfPages)); + + if (BufferAddress != NULL) { + *BufferAddress = CommRegionHob->PhysicalStart; + } + + Status = EFI_SUCCESS; + +Done: + return Status; +} + /** Entry point of MM communication buffer initialization module in PEI phase. @@ -127,13 +209,13 @@ MmCommunicationBufferPeiEntry ( EFI_PHYSICAL_ADDRESS SupvBufferAddr; EFI_PHYSICAL_ADDRESS UserBufferAddr; - Status = ReserveCommBuffer (MM_SUPERVISOR_BUFFER_T, PcdGet64 (PcdSupervisorCommBufferPages), &SupvBufferAddr); + Status = ReserveSupvCommBuffer (PcdGet64 (PcdSupervisorCommBufferPages), &SupvBufferAddr); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a Failed to reserve communicate buffer for supervisor - %r!\n", __FUNCTION__, Status)); goto Done; } - Status = ReserveCommBuffer (MM_USER_BUFFER_T, PcdGet64 (PcdUserCommBufferPages), &UserBufferAddr); + Status = ReserveUserCommBuffer (PcdGet64 (PcdUserCommBufferPages), &UserBufferAddr); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a Failed to reserve communicate buffer for user - %r!\n", __FUNCTION__, Status)); goto Done; diff --git a/MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.inf b/MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.inf index 86ac0362..94e5690a 100644 --- a/MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.inf +++ b/MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.inf @@ -41,6 +41,7 @@ [Guids] gMmCommonRegionHobGuid ## PRODUCES + gMmCommBufferHobGuid ## PRODUCES [Ppis] gMmCommunicationBufferReadyPpiGuid ## PRODUCES From 2621cfb252a4f3980efbc2a71ccd494bb3e45b47 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Sun, 5 Oct 2025 00:33:13 -0700 Subject: [PATCH 04/36] handle core --- MmSupervisorPkg/Core/Dispatcher/Dispatcher.c | 4 +- MmSupervisorPkg/Core/Mem/Mem.h | 1 - .../Core/Mem/SmmCpuMemoryManagement.c | 12 +- MmSupervisorPkg/Core/MmSupervisorCore.c | 590 +++++++-------- MmSupervisorPkg/Core/MmSupervisorCore.h | 8 +- MmSupervisorPkg/Core/MmSupervisorCore.inf | 2 +- MmSupervisorPkg/Core/Policy/GeneralPolicy.c | 599 ---------------- MmSupervisorPkg/Core/Policy/MemPolicy.c | 672 ------------------ MmSupervisorPkg/Core/Policy/Policy.h | 117 --- MmSupervisorPkg/Core/Relocate/Relocate.h | 1 - .../Core/Request/UpdateCommBuffer.c | 31 +- 11 files changed, 333 insertions(+), 1704 deletions(-) delete mode 100644 MmSupervisorPkg/Core/Policy/GeneralPolicy.c delete mode 100644 MmSupervisorPkg/Core/Policy/MemPolicy.c delete mode 100644 MmSupervisorPkg/Core/Policy/Policy.h diff --git a/MmSupervisorPkg/Core/Dispatcher/Dispatcher.c b/MmSupervisorPkg/Core/Dispatcher/Dispatcher.c index 848888ec..248f577d 100644 --- a/MmSupervisorPkg/Core/Dispatcher/Dispatcher.c +++ b/MmSupervisorPkg/Core/Dispatcher/Dispatcher.c @@ -797,7 +797,9 @@ MmAddToDriverList ( return EFI_SUCCESS; } - +#define COMM_BUFFER_MM_DISPATCH_ERROR 0x00 +#define COMM_BUFFER_MM_DISPATCH_SUCCESS 0x01 +#define COMM_BUFFER_MM_DISPATCH_RESTART 0x02 /** This function is the main entry point for an SMM handler dispatch or communicate-based callback. diff --git a/MmSupervisorPkg/Core/Mem/Mem.h b/MmSupervisorPkg/Core/Mem/Mem.h index c30de343..64e1fbf9 100644 --- a/MmSupervisorPkg/Core/Mem/Mem.h +++ b/MmSupervisorPkg/Core/Mem/Mem.h @@ -12,7 +12,6 @@ #ifndef _MM_CORE_MEM_H_ #define _MM_CORE_MEM_H_ -#include #include /// diff --git a/MmSupervisorPkg/Core/Mem/SmmCpuMemoryManagement.c b/MmSupervisorPkg/Core/Mem/SmmCpuMemoryManagement.c index 573d6593..f8839a7e 100644 --- a/MmSupervisorPkg/Core/Mem/SmmCpuMemoryManagement.c +++ b/MmSupervisorPkg/Core/Mem/SmmCpuMemoryManagement.c @@ -1632,8 +1632,8 @@ IsSmmCommBufferForbiddenAddress ( } } - if ((Address >= (EFI_PHYSICAL_ADDRESS)(UINTN)gMmCoreMailbox) && - (Address < (EFI_PHYSICAL_ADDRESS)(UINTN)gMmCoreMailbox + ((sizeof (MM_CORE_PRIVATE_DATA) + EFI_PAGE_SIZE -1) & ~(EFI_PAGE_SIZE -1)))) + if ((Address >= (EFI_PHYSICAL_ADDRESS)(UINTN)mMmCommMailboxBufferStatus) && + (Address < (EFI_PHYSICAL_ADDRESS)(UINTN)mMmCommMailboxBufferStatus + ((sizeof (mMmCommMailboxBufferStatus) + EFI_PAGE_SIZE -1) & ~(EFI_PAGE_SIZE -1)))) { return FALSE; } @@ -2322,8 +2322,8 @@ SetCommonBufferRegionAttribute ( } else { // Sanity check on the comm buffers and the mailbox data region if (InternalIsBufferOverlapped ( - (UINT8 *)gMmCoreMailbox, - sizeof (MM_CORE_PRIVATE_DATA), + (UINT8 *)mMmCommMailboxBufferStatus, + sizeof (MM_COMM_BUFFER_STATUS), (UINT8 *)(UINTN)mMmSupervisorAccessBuffer[Index].PhysicalStart, EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[Index].NumberOfPages) )) @@ -2350,8 +2350,8 @@ SetCommonBufferRegionAttribute ( // is the difference if you will need it for common buffer anyway? // Remove RX set above ZeroMem (&UnblockRegionParams.MemoryDescriptor, sizeof (EFI_MEMORY_DESCRIPTOR)); - UnblockRegionParams.MemoryDescriptor.PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)gMmCoreMailbox; - UnblockRegionParams.MemoryDescriptor.NumberOfPages = EFI_SIZE_TO_PAGES ((sizeof (MM_CORE_PRIVATE_DATA) + EFI_PAGE_MASK) & ~(EFI_PAGE_MASK)); + UnblockRegionParams.MemoryDescriptor.PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)mMmCommMailboxBufferStatus; + UnblockRegionParams.MemoryDescriptor.NumberOfPages = EFI_SIZE_TO_PAGES ((sizeof (mMmCommMailboxBufferStatus) + EFI_PAGE_MASK) & ~(EFI_PAGE_MASK)); UnblockRegionParams.MemoryDescriptor.Attribute = EFI_MEMORY_XP | EFI_MEMORY_SP; UnblockRegionParams.MemoryDescriptor.Type = EfiRuntimeServicesData; Status = ProcessUnblockPages (&UnblockRegionParams); diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.c b/MmSupervisorPkg/Core/MmSupervisorCore.c index 516c098f..68a3da91 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.c +++ b/MmSupervisorPkg/Core/MmSupervisorCore.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -39,10 +40,10 @@ MmDispatcher ( EFI_HANDLE mMmCpuHandle = NULL; // -// Physical pointer to private structure shared between MM IPL and the MM Core +// Physical pointer to MM_COMM_BUFFER structure shared between MM IPL and the MM Core // -MM_CORE_PRIVATE_DATA gMmCorePrivate; -MM_CORE_PRIVATE_DATA *gMmCoreMailbox = NULL; +MM_COMM_BUFFER_STATUS mMmCommunicationBufferStatus; +MM_COMM_BUFFER_STATUS *mMmCommMailboxBufferStatus = NULL; // // Ring 3 Hob pointer @@ -169,126 +170,164 @@ PrepareCommonBuffers ( { EFI_PEI_HOB_POINTERS GuidHob; MM_COMM_REGION_HOB *CommRegionHob; + MM_COMM_BUFFER *UserCommRegionHob; EFI_STATUS Status; UINTN Index; - VOID *HobData; - MM_CORE_DATA_HOB_DATA *DataInHob; for (Index = 0; Index < MM_OPEN_BUFFER_CNT; Index++) { ZeroMem (&mMmSupervisorAccessBuffer[Index], sizeof (EFI_MEMORY_DESCRIPTOR)); } GuidHob.Guid = GetFirstGuidHob (&gMmCommonRegionHobGuid); - while (GuidHob.Guid != NULL) { - CommRegionHob = GET_GUID_HOB_DATA (GuidHob.Guid); - if (CommRegionHob->MmCommonRegionType < MM_OPEN_BUFFER_CNT) { - if (mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].PhysicalStart != 0) { - DEBUG ((DEBUG_ERROR, "%a - Duplicated hobs for type %x!!\n", __FUNCTION__, CommRegionHob->MmCommonRegionType)); - Status = EFI_ALREADY_STARTED; - goto Exit; - } - - if (!MmIsBufferOutsideMmValid ( - mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].PhysicalStart, - EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].NumberOfPages) - )) - { - DEBUG (( - DEBUG_ERROR, - "%a - Buffer (%p) invalid for type %x!!\n", - __FUNCTION__, - mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].PhysicalStart, - CommRegionHob->MmCommonRegionType - )); - Status = EFI_BAD_BUFFER_SIZE; - ASSERT (FALSE); - goto Exit; - } - - mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].PhysicalStart = CommRegionHob->MmCommonRegionAddr; - mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].NumberOfPages = CommRegionHob->MmCommonRegionPages; - // But the memory itself is allocated under reserved.. - mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].Type = EfiRuntimeServicesData; - mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].Attribute = EFI_MEMORY_XP | EFI_MEMORY_SP; - if (CommRegionHob->MmCommonRegionType == MM_SUPERVISOR_BUFFER_T) { - Status = MmAllocateSupervisorPages ( - AllocateAnyPages, - EfiRuntimeServicesData, - CommRegionHob->MmCommonRegionPages, - (EFI_PHYSICAL_ADDRESS *)&mInternalCommBufferCopy[CommRegionHob->MmCommonRegionType] - ); - } else { - Status = MmAllocatePages ( - AllocateAnyPages, - EfiRuntimeServicesData, - CommRegionHob->MmCommonRegionPages, - (EFI_PHYSICAL_ADDRESS *)&mInternalCommBufferCopy[CommRegionHob->MmCommonRegionType] - ); - } - - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to allocate internal buffer copy, please consider adjust TSEG size... - %r\n", __FUNCTION__, Status)); - goto Exit; - } + CommRegionHob = GET_GUID_HOB_DATA (GuidHob.Guid); + if (CommRegionHob->MmCommonRegionType == MM_SUPERVISOR_BUFFER_T) { + if (mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].PhysicalStart != 0) { + DEBUG ((DEBUG_ERROR, "%a - Duplicated hobs for type %x!!\n", __func__, CommRegionHob->MmCommonRegionType)); + Status = EFI_ALREADY_STARTED; + goto Exit; + } - mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].VirtualStart = 0; + if (!MmIsBufferOutsideMmValid ( + mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].PhysicalStart, + EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].NumberOfPages) + )) + { DEBUG (( - DEBUG_INFO, - "%a - Populating MM Access Buffer Type %d to 0x%p with 0x%x pages\n", - __FUNCTION__, - CommRegionHob->MmCommonRegionType, + DEBUG_ERROR, + "%a - Buffer (%p) invalid for type %x!!\n", + __func__, mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].PhysicalStart, - mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].NumberOfPages + CommRegionHob->MmCommonRegionType )); + Status = EFI_BAD_BUFFER_SIZE; + ASSERT (FALSE); + goto Exit; + } + + mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].PhysicalStart = CommRegionHob->MmCommonRegionAddr; + mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].NumberOfPages = CommRegionHob->MmCommonRegionPages; + // But the memory itself is allocated under reserved.. + mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].Type = EfiRuntimeServicesData; + mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].Attribute = EFI_MEMORY_XP | EFI_MEMORY_SP; + if (CommRegionHob->MmCommonRegionType == MM_SUPERVISOR_BUFFER_T) { + Status = MmAllocateSupervisorPages ( + AllocateAnyPages, + EfiRuntimeServicesData, + CommRegionHob->MmCommonRegionPages, + (EFI_PHYSICAL_ADDRESS *)&mInternalCommBufferCopy[CommRegionHob->MmCommonRegionType] + ); + } else { + Status = MmAllocatePages ( + AllocateAnyPages, + EfiRuntimeServicesData, + CommRegionHob->MmCommonRegionPages, + (EFI_PHYSICAL_ADDRESS *)&mInternalCommBufferCopy[CommRegionHob->MmCommonRegionType] + ); } - GuidHob.Guid = GET_NEXT_HOB (GuidHob); - GuidHob.Guid = GetNextGuidHob (&gMmCommonRegionHobGuid, GuidHob.Guid); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Failed to allocate internal buffer copy, please consider adjust TSEG size... - %r\n", __func__, Status)); + goto Exit; + } + + mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].VirtualStart = 0; + DEBUG (( + DEBUG_INFO, + "%a - Populating MM Access Buffer Type %d to 0x%p with 0x%x pages\n", + __func__, + CommRegionHob->MmCommonRegionType, + mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].PhysicalStart, + mMmSupervisorAccessBuffer[CommRegionHob->MmCommonRegionType].NumberOfPages + )); + } else { + DEBUG ((DEBUG_ERROR, "%a - Invalid common buffer type %x." + "Please make sure the user buffer is published through gMmCommBufferHobGuid!!\n", __func__, CommRegionHob->MmCommonRegionType)); + Status = EFI_UNSUPPORTED; + goto Exit; + } + + // Cover the user level buffer, through the EDK2 way... + GuidHob.Guid = GetFirstGuidHob (&gMmCommBufferHobGuid); + if (GuidHob.Guid == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to find MM Communication Buffer HOB\n")); + DEBUG ((DEBUG_ERROR, "Only Root MMI Handlers will be supported!\n")); + Status = EFI_NOT_FOUND; + goto Exit; } + UserCommRegionHob = (MM_COMM_BUFFER *)GET_GUID_HOB_DATA (GuidHob); + DEBUG (( + DEBUG_INFO, + "MM Communication Buffer is at %x, number of pages is %x\n", + UserCommRegionHob->PhysicalStart, + UserCommRegionHob->NumberOfPages + )); + ASSERT (UserCommRegionHob->PhysicalStart != 0 && UserCommRegionHob->NumberOfPages != 0); + + if (!MmIsBufferOutsideMmValid ( + UserCommRegionHob->PhysicalStart, + EFI_PAGES_TO_SIZE (UserCommRegionHob->NumberOfPages) + )) + { + UserCommRegionHob = NULL; + DEBUG ((DEBUG_ERROR, "MM Communication Buffer is invalid!\n")); + Status = EFI_BAD_BUFFER_SIZE; + ASSERT (FALSE); + goto Exit; + } + + mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].PhysicalStart = UserCommRegionHob->PhysicalStart; + mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages = UserCommRegionHob->NumberOfPages; + // But the memory itself is allocated under reserved.. + mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].Type = EfiRuntimeServicesData; + mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].Attribute = EFI_MEMORY_XP | EFI_MEMORY_SP; Status = MmAllocatePages ( - AllocateAnyPages, - EfiRuntimeServicesData, - DEFAULT_SUPV_TO_USER_BUFFER_PAGE, - (EFI_PHYSICAL_ADDRESS *)&SupervisorToUserDataBuffer - ); + AllocateAnyPages, + EfiRuntimeServicesData, + UserCommRegionHob->NumberOfPages, + (EFI_PHYSICAL_ADDRESS *)&mInternalCommBufferCopy[MM_USER_BUFFER_T] + ); + ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to allocate supervisor to user buffer, cannot continue...\n", __FUNCTION__)); + DEBUG ((DEBUG_ERROR, "%a - Failed to allocate internal buffer copy, please consider adjust TSEG size... - %r\n", __func__, Status)); goto Exit; } - // Here we disclose some fundamental information to ring 3 world, such as MmRanges - ZeroMem (SupervisorToUserDataBuffer, sizeof (MM_SUPV_USER_COMMON_BUFFER)); - SupervisorToUserDataBuffer->gMmCorePrivateDummy.MmramRangeCount = gMmCorePrivate.MmramRangeCount; - Status = MmAllocatePages ( - AllocateAnyPages, - EfiRuntimeServicesData, - EFI_SIZE_TO_PAGES (gMmCorePrivate.MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR)), - &(SupervisorToUserDataBuffer->gMmCorePrivateDummy.MmramRanges) - ); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to allocate supervisor to user buffer, cannot continue...\n", __FUNCTION__)); + mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].VirtualStart = 0; + DEBUG (( + DEBUG_INFO, + "%a - Populating MM Access Buffer Type %d to 0x%p with 0x%x pages\n", + __func__, + MM_USER_BUFFER_T, + mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].PhysicalStart, + mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages + )); + + mMmCommMailboxBufferStatus = (MM_COMM_BUFFER_STATUS*)(UINTN)UserCommRegionHob->Status; + if (mMmCommMailboxBufferStatus == NULL) { + DEBUG ((DEBUG_ERROR, "%a - Invalid MM Communication Buffer Status pointer!\n", __func__)); + Status = EFI_INVALID_PARAMETER; goto Exit; } - CopyMem ( - (VOID *)SupervisorToUserDataBuffer->gMmCorePrivateDummy.MmramRanges, - (VOID *)gMmCorePrivate.MmramRanges, - gMmCorePrivate.MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR) - ); - HobData = GetNextGuidHob (&gMmCoreDataHobGuid, mMmHobStart); - if (HobData != NULL) { - // Only relink the dummy private data if needed - DataInHob = GET_GUID_HOB_DATA (HobData); - DataInHob->Address = (EFI_PHYSICAL_ADDRESS)(UINTN)SupervisorToUserDataBuffer; + Status = MmAllocatePages ( + AllocateAnyPages, + EfiRuntimeServicesData, + DEFAULT_SUPV_TO_USER_BUFFER_PAGE, + (EFI_PHYSICAL_ADDRESS *)&SupervisorToUserDataBuffer + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Failed to allocate supervisor to user buffer, cannot continue...\n", __func__)); + goto Exit; } Exit: if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to prepare communicate buffer for Standalone MM environment... - %r\n", __FUNCTION__, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to prepare communicate buffer for Standalone MM environment... - %r\n", __func__, Status)); + ZeroMem (mMmSupervisorAccessBuffer, sizeof (mMmSupervisorAccessBuffer)); } return Status; @@ -442,116 +481,122 @@ MmEntryPoint ( // // Mark the InMm flag as TRUE // - if (gMmCoreMailbox != NULL) { - gMmCoreMailbox->InMm = TRUE; - CopyMem (&gMmCorePrivate, gMmCoreMailbox, sizeof (MM_CORE_PRIVATE_DATA)); - } + if (mMmCommMailboxBufferStatus != NULL) { + CopyMem (&mMmCommunicationBufferStatus, (MM_COMM_BUFFER_STATUS*)(UINTN)mMmCommMailboxBufferStatus, sizeof (MM_COMM_BUFFER_STATUS)); - gMmCorePrivate.InMm = TRUE; + if (mMmCommunicationBufferStatus.IsCommBufferValid) { + if (mMmCommunicationBufferStatus.CommunicateChannel == MM_SUPERVISOR_BUFFER_T) { + CommunicationBuffer = mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].PhysicalStart; + } else { + CommunicationBuffer = mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].PhysicalStart; + } - // - // Check to see if this is a Synchronous MMI sent through the MM Communication - // Protocol or an Asynchronous MMI - // - CommunicationBuffer = (EFI_PHYSICAL_ADDRESS)(UINTN)gMmCorePrivate.CommunicationBuffer; - BufferSize = gMmCorePrivate.BufferSize; - if ((VOID *)CommunicationBuffer != NULL) { - // - // Synchronous MMI for MM Core or request from Communicate protocol - // - if ((CommunicationBuffer == mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].PhysicalStart) && - (BufferSize <= EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages))) - { // - // This should be user communicate channel, follow normal user channel iterations, but use ring 3 buffer to hold BufferSize changes + // Synchronous MMI for MM Core or request from Communicate protocol // - ZeroMem (mInternalCommBufferCopy[MM_USER_BUFFER_T], EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages)); - CopyMem (mInternalCommBufferCopy[MM_USER_BUFFER_T], (VOID *)(UINTN)CommunicationBuffer, BufferSize); - CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mInternalCommBufferCopy[MM_USER_BUFFER_T]; + if (CommunicationBuffer == mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].PhysicalStart) { + // + // This should be user communicate channel, follow normal user channel iterations, but use ring 3 buffer to hold BufferSize changes + // + ZeroMem (mInternalCommBufferCopy[MM_USER_BUFFER_T], EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages)); + CopyMem (mInternalCommBufferCopy[MM_USER_BUFFER_T], (VOID *)(UINTN)CommunicationBuffer, EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages)); + CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mInternalCommBufferCopy[MM_USER_BUFFER_T]; + + // + // Now that we operate on the copy + // + SupervisorToUserDataBuffer->UserBufferSize = CommunicateHeader->MessageLength; + if (SupervisorToUserDataBuffer->UserBufferSize > EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages)) { + // The input buffer size is larger than the maximal allowed size, need to panic here. + DEBUG ((DEBUG_ERROR, "%a Input buffer size is larger than maximal allowed user buffer size, something is off...\n", __func__)); + ASSERT (FALSE); + mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; + mMmCommunicationBufferStatus.ReturnBufferSize = 0; + mMmCommunicationBufferStatus.ReturnStatus = EFI_BAD_BUFFER_SIZE; + goto Cleanup; + } - Status = SafeUint64Sub (BufferSize, OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data), &BufferSize); - if (EFI_ERROR (Status)) { - gMmCorePrivate.CommunicationBuffer = 0; - gMmCorePrivate.ReturnStatus = EFI_ACCESS_DENIED; - // Note: this will cause another difference compared to PiSmmCore, - // as the normal one will handle asynchronous MMI sources. - goto Cleanup; - } + Status = MmiManage ( + &CommunicateHeader->HeaderGuid, + NULL, + CommunicateHeader->Data, + (UINTN *)&(SupervisorToUserDataBuffer->UserBufferSize) + ); + // + // Update CommunicationBuffer, BufferSize and ReturnStatus + // Communicate service finished, reset the pointer to CommBuffer to NULL + // + BufferSize = SupervisorToUserDataBuffer->UserBufferSize + + OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data); + if (BufferSize <= EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages)) { + CopyMem ((VOID *)(UINTN)CommunicationBuffer, CommunicateHeader, BufferSize); + } else { + // The returned buffer size indicating the return buffer is larger than input buffer, need to panic here. + DEBUG ((DEBUG_ERROR, "%a Returned buffer size is larger than maximal allowed size indicated in input, something is off...\n", __func__)); + ASSERT (FALSE); + } - SupervisorToUserDataBuffer->gMmCorePrivateDummy.BufferSize = BufferSize; - Status = MmiManage ( - &CommunicateHeader->HeaderGuid, - NULL, - CommunicateHeader->Data, - (UINTN *)&(SupervisorToUserDataBuffer->gMmCorePrivateDummy.BufferSize) - ); - // - // Update CommunicationBuffer, BufferSize and ReturnStatus - // Communicate service finished, reset the pointer to CommBuffer to NULL - // - BufferSize = SupervisorToUserDataBuffer->gMmCorePrivateDummy.BufferSize + - OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data); - if (BufferSize <= EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages)) { - CopyMem ((VOID *)(UINTN)CommunicationBuffer, CommunicateHeader, BufferSize); - } else { - // The returned buffer size indicating the return buffer is larger than input buffer, need to panic here. - DEBUG ((DEBUG_ERROR, "%a Returned buffer size is larger than maximal allowed size indicated in input, something is off...\n", __FUNCTION__)); - ASSERT (FALSE); - } + mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; + mMmCommunicationBufferStatus.ReturnBufferSize = BufferSize; + mMmCommunicationBufferStatus.ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; + } else if (CommunicationBuffer == mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].PhysicalStart) { + // + // This should be supervisor communicate channel, everything can be ring 0 buffer fine + // + ZeroMem (mInternalCommBufferCopy[MM_SUPERVISOR_BUFFER_T], EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].NumberOfPages)); + CopyMem (mInternalCommBufferCopy[MM_SUPERVISOR_BUFFER_T], (VOID *)(UINTN)CommunicationBuffer, EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].NumberOfPages)); + CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mInternalCommBufferCopy[MM_SUPERVISOR_BUFFER_T]; + + // + // Now that we operate on the copy + // + BufferSize = CommunicateHeader->MessageLength; + if (BufferSize > EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].NumberOfPages)) { + // The input buffer size is larger than the maximal allowed size, need to panic here. + DEBUG ((DEBUG_ERROR, "%a Input buffer size is larger than maximal allowed size, something is off...\n", __func__)); + ASSERT (FALSE); + mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; + mMmCommunicationBufferStatus.ReturnBufferSize = 0; + mMmCommunicationBufferStatus.ReturnStatus = EFI_BAD_BUFFER_SIZE; + goto Cleanup; + } - gMmCorePrivate.BufferSize = BufferSize; - gMmCorePrivate.CommunicationBuffer = 0; - gMmCorePrivate.ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; - } else if ((CommunicationBuffer == mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].PhysicalStart) && - (BufferSize <= EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].NumberOfPages))) - { - // - // This should be supervisor communicate channel, everything can be ring 0 buffer fine - // - ZeroMem (mInternalCommBufferCopy[MM_SUPERVISOR_BUFFER_T], EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].NumberOfPages)); - CopyMem (mInternalCommBufferCopy[MM_SUPERVISOR_BUFFER_T], (VOID *)(UINTN)CommunicationBuffer, BufferSize); - CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mInternalCommBufferCopy[MM_SUPERVISOR_BUFFER_T]; + Status = MmiManage ( + &CommunicateHeader->HeaderGuid, + NULL, + CommunicateHeader->Data, + (UINTN *)&BufferSize + ); + // + // Update CommunicationBuffer, BufferSize and ReturnStatus + // Communicate service finished, reset the pointer to CommBuffer to NULL + // + BufferSize = BufferSize + OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data); + if (BufferSize <= EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].NumberOfPages)) { + CopyMem ((VOID *)(UINTN)mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].PhysicalStart, CommunicateHeader, BufferSize); + } else { + // The returned buffer size indicating the return buffer is larger than input buffer, need to panic here. + DEBUG ((DEBUG_ERROR, "%a Returned buffer size is larger than maximal allowed size indicated in input, something is off...\n", __func__)); + ASSERT (FALSE); + } - Status = SafeUint64Sub (BufferSize, OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data), &BufferSize); - if (EFI_ERROR (Status)) { - gMmCorePrivate.CommunicationBuffer = 0; - gMmCorePrivate.ReturnStatus = EFI_ACCESS_DENIED; + mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; + mMmCommunicationBufferStatus.ReturnBufferSize = BufferSize; + mMmCommunicationBufferStatus.ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; + // + // Do not handle asynchronous MMI sources. This cannot be it... + // goto Cleanup; - } - - Status = MmiManage ( - &CommunicateHeader->HeaderGuid, - NULL, - CommunicateHeader->Data, - (UINTN *)&BufferSize - ); - // - // Update CommunicationBuffer, BufferSize and ReturnStatus - // Communicate service finished, reset the pointer to CommBuffer to NULL - // - BufferSize = BufferSize + OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data); - if (BufferSize <= EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].NumberOfPages)) { - CopyMem ((VOID *)(UINTN)mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].PhysicalStart, CommunicateHeader, BufferSize); } else { - // The returned buffer size indicating the return buffer is larger than input buffer, need to panic here. - DEBUG ((DEBUG_ERROR, "%a Returned buffer size is larger than maximal allowed size indicated in input, something is off...\n", __FUNCTION__)); - ASSERT (FALSE); + // + // If CommunicationBuffer is not in valid address scope, return EFI_ACCESS_DENIED + // + mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; + mMmCommunicationBufferStatus.ReturnStatus = EFI_ACCESS_DENIED; } - - gMmCorePrivate.BufferSize = BufferSize; - gMmCorePrivate.CommunicationBuffer = 0; - gMmCorePrivate.ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; - // - // Do not handle asynchronous MMI sources. This cannot be it... - // - goto Cleanup; - } else { - // - // If CommunicationBuffer is not in valid address scope, return EFI_ACCESS_DENIED - // - gMmCorePrivate.CommunicationBuffer = 0; - gMmCorePrivate.ReturnStatus = EFI_ACCESS_DENIED; } + } else { + DEBUG ((DEBUG_INFO, "No valid communication buffer, no Synchronous MMI will be processed\n")); } // @@ -567,10 +612,8 @@ MmEntryPoint ( // // Clear the InMm flag as we are going to leave MM // - gMmCorePrivate.InMm = FALSE; - if (gMmCoreMailbox != NULL) { - CopyMem (gMmCoreMailbox, &gMmCorePrivate, sizeof (MM_CORE_PRIVATE_DATA)); - gMmCoreMailbox->InMm = FALSE; + if (mMmCommMailboxBufferStatus != NULL) { + CopyMem (mMmCommMailboxBufferStatus, &mMmCommunicationBufferStatus, sizeof (MM_COMM_BUFFER_STATUS)); } DEBUG ((DEBUG_VERBOSE, "MmEntryPoint Done\n")); @@ -596,19 +639,13 @@ MmConfigurationMmNotify ( // // Register the MM Entry Point provided by the MM Core with the MM COnfiguration protocol // - Status = MmConfiguration->RegisterMmEntry (MmConfiguration, (EFI_MM_ENTRY_POINT)(UINTN)gMmCorePrivate.MmEntryPoint); + Status = MmConfiguration->RegisterMmEntry (MmConfiguration, (EFI_MM_ENTRY_POINT)MmEntryPoint); ASSERT_EFI_ERROR (Status); - // - // Set flag to indicate that the MM Entry Point has been registered which - // means that MMIs are now fully operational. - // - gMmCorePrivate.MmEntryPointRegistered = TRUE; - // // Print debug message showing MM Core entry point address. // - DEBUG ((DEBUG_INFO, "MM Core registered MM Entry Point address %p\n", (VOID *)(UINTN)gMmCorePrivate.MmEntryPoint)); + DEBUG ((DEBUG_INFO, "MM Core registered MM Entry Point address %p\n", (VOID *)(UINTN)MmEntryPoint)); return EFI_SUCCESS; } @@ -640,7 +677,27 @@ MmCoreInstallLoadedImage ( VOID ) { - EFI_STATUS Status; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS MmCoreImageBaseAddress; + UINT64 MmCoreImageLength; + EFI_PEI_HOB_POINTERS Hob; + + // + // TODO: This deviates from the EDK2 implementation which uses the memory allocation + // module to retrieve the memory allocation HOB. + // Searching for Memory Allocation HOB + // + Hob.Raw = GetHobList (); + Hob.Raw = GetNextMemoryAllocationGuidHob (&gMmSupervisorCoreGuid, Hob.Raw); + + if (Hob.Raw == NULL) { + DEBUG ((DEBUG_ERROR, "MM Core Memory Allocation HOB not found!\n")); + ASSERT (FALSE); + return; + } + + MmCoreImageBaseAddress = Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress; + MmCoreImageLength = Hob.MemoryAllocation->AllocDescriptor.MemoryLength; // // Allocate a Loaded Image Protocol in MM @@ -665,14 +722,14 @@ MmCoreInstallLoadedImage ( mMmCoreDriverEntry->LoadedImage->DeviceHandle = NULL; mMmCoreDriverEntry->LoadedImage->FilePath = NULL; - mMmCoreDriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)gMmCorePrivate.MmCoreImageBase; - mMmCoreDriverEntry->LoadedImage->ImageSize = gMmCorePrivate.MmCoreImageSize; + mMmCoreDriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)MmCoreImageBaseAddress; + mMmCoreDriverEntry->LoadedImage->ImageSize = MmCoreImageLength; mMmCoreDriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode; mMmCoreDriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData; - mMmCoreDriverEntry->ImageEntryPoint = gMmCorePrivate.MmCoreEntryPoint; - mMmCoreDriverEntry->ImageBuffer = gMmCorePrivate.MmCoreImageBase; - mMmCoreDriverEntry->NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)gMmCorePrivate.MmCoreImageSize); + mMmCoreDriverEntry->ImageEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)MmSupervisorMain; + mMmCoreDriverEntry->ImageBuffer = MmCoreImageBaseAddress; + mMmCoreDriverEntry->NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)MmCoreImageLength); // // Create a new image handle in the MM handle database for the MM Driver @@ -702,7 +759,7 @@ MmCoreInstallLoadedImage ( **/ EFI_STATUS DiscoverStandaloneMmDriversInFvHobs ( - VOID + IN EFI_PHYSICAL_ADDRESS *StandaloneBfvAddress ) { UINT16 ExtHeaderOffset; @@ -725,7 +782,7 @@ DiscoverStandaloneMmDriversInFvHobs ( DEBUG (( DEBUG_INFO, "[%a] Found FV HOB referencing FV at 0x%x. Size is 0x%x.\n", - __FUNCTION__, + __func__, (UINTN)FwVolHeader, FwVolHeader->FvLength )); @@ -733,7 +790,7 @@ DiscoverStandaloneMmDriversInFvHobs ( ExtHeaderOffset = ReadUnaligned16 (&FwVolHeader->ExtHeaderOffset); if (ExtHeaderOffset != 0) { ExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FwVolHeader + ExtHeaderOffset); - DEBUG ((DEBUG_INFO, "[%a] FV GUID = {%g}.\n", __FUNCTION__, &ExtHeader->FvName)); + DEBUG ((DEBUG_INFO, "[%a] FV GUID = {%g}.\n", __func__, &ExtHeader->FvName)); } // @@ -748,11 +805,11 @@ DiscoverStandaloneMmDriversInFvHobs ( ); if (!EFI_ERROR (Status)) { if (CompareGuid (&FileHeader->Name, &gMmSupervisorCoreGuid)) { - gMmCorePrivate.StandaloneBfvAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)FwVolHeader; + *StandaloneBfvAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)FwVolHeader; DEBUG (( DEBUG_INFO, "[%a] Discovered Standalone MM Core [%g] in FV at 0x%x.\n", - __FUNCTION__, + __func__, &gEfiCallerIdGuid, (UINTN)FwVolHeader )); @@ -770,7 +827,7 @@ DiscoverStandaloneMmDriversInFvHobs ( DEBUG (( DEBUG_INFO, "[%a] Adding Standalone MM drivers in FV at 0x%x to the dispatch list.\n", - __FUNCTION__, + __func__, (UINTN)FwVolHeader )); Status = MmCoreFfsFindMmDriver (FwVolHeader); @@ -787,13 +844,15 @@ DiscoverStandaloneMmDriversInFvHobs ( /** Routine for initializing policy data provided by firmware. + @param StandaloneBfvAddress The base address of the FV that contains the policy file. + @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. @retval Errors The supervisor is unable to locate or protect the policy from firmware. **/ EFI_STATUS InitializePolicy ( - VOID + IN EFI_PHYSICAL_ADDRESS StandaloneBfvAddress ) { EFI_STATUS Status; @@ -811,14 +870,14 @@ InitializePolicy ( do { Status = FfsFindNextFile ( EFI_FV_FILETYPE_FREEFORM, - (EFI_FIRMWARE_VOLUME_HEADER *)gMmCorePrivate.StandaloneBfvAddress, + (EFI_FIRMWARE_VOLUME_HEADER *)StandaloneBfvAddress, &FileHeader ); if (EFI_ERROR (Status)) { DEBUG (( DEBUG_ERROR, "[%a] Failed to locate firmware policy file from given FV - %r\n", - __FUNCTION__, + __func__, Status )); break; @@ -831,7 +890,7 @@ InitializePolicy ( DEBUG (( DEBUG_INFO, "[%a] Discovered policy file in FV at 0x%p.\n", - __FUNCTION__, + __func__, FileHeader )); @@ -845,7 +904,7 @@ InitializePolicy ( DEBUG (( DEBUG_ERROR, "[%a] Failed to find raw section from discovered policy file - %r\n", - __FUNCTION__, + __func__, Status )); break; @@ -856,7 +915,7 @@ InitializePolicy ( DEBUG (( DEBUG_ERROR, "[%a] Policy data size 0x%x > blob size 0x%x.\n", - __FUNCTION__, + __func__, PolicySize, SectionDataSize )); @@ -870,7 +929,7 @@ InitializePolicy ( DEBUG (( DEBUG_ERROR, "[%a] Cannot allocate page for firmware provided policy - %r\n", - __FUNCTION__, + __func__, Status )); break; @@ -887,7 +946,7 @@ InitializePolicy ( } while (TRUE); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Unable to locate a valid firmware policy from given FV, bail here - %r\n", __FUNCTION__, Status)); + DEBUG ((DEBUG_ERROR, "%a Unable to locate a valid firmware policy from given FV, bail here - %r\n", __func__, Status)); ASSERT_EFI_ERROR (Status); goto Done; } @@ -895,14 +954,14 @@ InitializePolicy ( // Prepare the buffer for Mem policy snapshot, it will be compared against when non-MM entity requested Status = AllocateMemForPolicySnapshot (&MemPolicySnapshot); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Failed to allocate buffer for memory policy snapshot - %r\n", __FUNCTION__, Status)); + DEBUG ((DEBUG_ERROR, "%a Failed to allocate buffer for memory policy snapshot - %r\n", __func__, Status)); ASSERT_EFI_ERROR (Status); goto Done; } Status = SecurityPolicyCheck (FirmwarePolicy); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Policy check failed on policy blob from firmware - %r\n", __FUNCTION__, Status)); + DEBUG ((DEBUG_ERROR, "%a Policy check failed on policy blob from firmware - %r\n", __func__, Status)); ASSERT_EFI_ERROR (Status); goto Done; } @@ -934,68 +993,36 @@ MmSupervisorMain ( EFI_STATUS Status; UINTN Index; VOID *Registration; - EFI_HOB_GUID_TYPE *GuidHob; - MM_CORE_DATA_HOB_DATA *DataInHob; EFI_HOB_GUID_TYPE *MmramRangesHob; EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData; EFI_MMRAM_DESCRIPTOR *MmramRanges; UINTN MmramRangeCount; UINT64 StartTicker; UINT64 EndTicker; + EFI_PHYSICAL_ADDRESS StandaloneBfvAddress; MmSupervisorCoreEntryInit (); DEBUG ((DEBUG_INFO, "MmMain - 0x%x\n", HobStart)); // - // Determine if the caller has passed a reference to a MM_CORE_PRIVATE_DATA - // structure in the Hoblist. This choice will govern how boot information is - // extracted later. + // Extract the MMRAM ranges from the MMRAM descriptor HOB // - GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart); - if (GuidHob == NULL) { - // - // Allocate and zero memory for a MM_CORE_PRIVATE_DATA table and then - // initialise it - // - SetMem ((VOID *)&gMmCorePrivate, sizeof (MM_CORE_PRIVATE_DATA), 0); - gMmCorePrivate.Signature = MM_CORE_PRIVATE_DATA_SIGNATURE; - gMmCorePrivate.MmEntryPointRegistered = FALSE; - gMmCorePrivate.InMm = FALSE; - gMmCorePrivate.ReturnStatus = EFI_SUCCESS; - - // - // Extract the MMRAM ranges from the MMRAM descriptor HOB - // - MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart); + MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart); + if (MmramRangesHob == NULL) { + MmramRangesHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid); if (MmramRangesHob == NULL) { - MmramRangesHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid); - if (MmramRangesHob == NULL) { - return EFI_UNSUPPORTED; - } + return EFI_UNSUPPORTED; } - - MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); - ASSERT (MmramRangesHobData != NULL); - MmramRanges = MmramRangesHobData->Descriptor; - MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions; - ASSERT (MmramRanges); - ASSERT (MmramRangeCount); - - // - // Copy the MMRAM ranges into MM_CORE_PRIVATE_DATA table just in case any - // code relies on them being present there - // - gMmCorePrivate.MmramRangeCount = (UINT64)MmramRangeCount; - } else { - DataInHob = GET_GUID_HOB_DATA (GuidHob); - gMmCoreMailbox = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address; - SetMem ((VOID *)&gMmCorePrivate, sizeof (MM_CORE_PRIVATE_DATA), 0); - CopyMem (&gMmCorePrivate, gMmCoreMailbox, sizeof (MM_CORE_PRIVATE_DATA)); - MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate.MmramRanges; - MmramRangeCount = (UINTN)gMmCorePrivate.MmramRangeCount; } + MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); + ASSERT (MmramRangesHobData != NULL); + MmramRanges = MmramRangesHobData->Descriptor; + MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions; + ASSERT (MmramRanges); + ASSERT (MmramRangeCount); + // // Print the MMRAM ranges passed by the caller // @@ -1027,11 +1054,6 @@ MmSupervisorMain ( ASSERT (mMmramRanges != NULL); CopyMem (mMmramRanges, (VOID *)(UINTN)MmramRanges, mMmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR)); - // Then we can use our own copy of MMRAM ranges - gMmCorePrivate.MmramRanges = (EFI_PHYSICAL_ADDRESS)(UINTN)mMmramRanges; - gMmCorePrivate.Mmst = (EFI_PHYSICAL_ADDRESS)(UINTN)&gMmCoreMmst; - gMmCorePrivate.MmEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)MmEntryPoint; - DEBUG ((DEBUG_INFO, "MmInstallConfigurationTable For HobList\n")); // // Install HobList @@ -1052,13 +1074,13 @@ MmSupervisorMain ( // Discover Standalone MM drivers for dispatch // StartTicker = GetPerformanceCounter (); - Status = DiscoverStandaloneMmDriversInFvHobs (); + Status = DiscoverStandaloneMmDriversInFvHobs (&StandaloneBfvAddress); EndTicker = GetPerformanceCounter (); ASSERT_EFI_ERROR (Status); DEBUG (( DEBUG_INFO, "Mm Dispatch StandaloneBfvAddress - 0x%08x, consumed %dms.\n", - gMmCorePrivate.StandaloneBfvAddress, + StandaloneBfvAddress, (GetTimeInNanoSecond (EndTicker - StartTicker) / 1000000) )); @@ -1095,14 +1117,14 @@ MmSupervisorMain ( Status = InitializeMmSupervisorTestAgents (); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Failed to initialize test agents - Status %d\n", __FUNCTION__, Status)); + DEBUG ((DEBUG_ERROR, "%a Failed to initialize test agents - Status %d\n", __func__, Status)); ASSERT (FALSE); goto Exit; } Status = PrepareCommonBuffers (); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Failed to prepare comm buffer - Status %d\n", __FUNCTION__, Status)); + DEBUG ((DEBUG_ERROR, "%a Failed to prepare comm buffer - Status %d\n", __func__, Status)); ASSERT (FALSE); goto Exit; } @@ -1111,7 +1133,7 @@ MmSupervisorMain ( MmCoreInitializeSmiHandlerProfile (); - InitializePolicy (); + InitializePolicy (StandaloneBfvAddress); CallgateInit (mNumberOfCpus); @@ -1123,17 +1145,13 @@ MmSupervisorMain ( mCoreInitializationComplete = TRUE; - if (gMmCoreMailbox != NULL) { - CopyMem (gMmCoreMailbox, &gMmCorePrivate, sizeof (MM_CORE_PRIVATE_DATA)); - } - PostRelocationRun (); DEBUG ((DEBUG_INFO, "MmMain Done!\n")); Exit: if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Standalone MM foundation not properly set, system may not boot - %r!\n", __FUNCTION__, Status)); + DEBUG ((DEBUG_ERROR, "%a Standalone MM foundation not properly set, system may not boot - %r!\n", __func__, Status)); } return Status; diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.h b/MmSupervisorPkg/Core/MmSupervisorCore.h index 9e9e62fc..322152b7 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.h +++ b/MmSupervisorPkg/Core/MmSupervisorCore.h @@ -31,9 +31,8 @@ #include #include #include +#include #include -#include -#include #include #include @@ -229,14 +228,13 @@ typedef struct { // Used to share data from supervisor to user space, nothing should be security sensitive // typedef struct { - MM_CORE_PRIVATE_DATA gMmCorePrivateDummy; + UINT64 UserBufferSize; } MM_SUPV_USER_COMMON_BUFFER; // // MM Core Global Variables // -extern MM_CORE_PRIVATE_DATA gMmCorePrivate; -extern MM_CORE_PRIVATE_DATA *gMmCoreMailbox; +extern MM_COMM_BUFFER_STATUS *mMmCommMailboxBufferStatus; extern EFI_MM_SYSTEM_TABLE gMmCoreMmst; extern EFI_MM_SYSTEM_TABLE *gMmUserMmst; extern LIST_ENTRY gHandleList; diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.inf b/MmSupervisorPkg/Core/MmSupervisorCore.inf index 6beab5cf..428ce3bd 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.inf +++ b/MmSupervisorPkg/Core/MmSupervisorCore.inf @@ -224,6 +224,7 @@ gMmCoreMmProfileGuid gMmCommonRegionHobGuid ## CONSUMES + gMmCommBufferHobGuid ## CONSUMES gMmProtectedRegionHobGuid ## SOMETIMES_CONSUMES gMmUnblockRegionHobGuid ## SOMETIMES_CONSUMES gMmSupervisorCoreGuid ## CONSUMES @@ -237,7 +238,6 @@ gMmPagingAuditMmiHandlerGuid ## SOMETIMES_CONSUMES gEfiHobMemoryAllocModuleGuid gEfiMmPeiMmramMemoryReserveGuid - gMmCoreDataHobGuid [BuildOptions.common] #Subsystem version will be used as MmSupervisor driver version diff --git a/MmSupervisorPkg/Core/Policy/GeneralPolicy.c b/MmSupervisorPkg/Core/Policy/GeneralPolicy.c deleted file mode 100644 index 56b16a41..00000000 --- a/MmSupervisorPkg/Core/Policy/GeneralPolicy.c +++ /dev/null @@ -1,599 +0,0 @@ -/** @file -Implementation of SMM policy related routine. - -Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
-Copyright (c) 2020, AMD Incorporated. All rights reserved.
-Copyright (c) Microsoft Corporation. -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include - -#include "MmSupervisorCore.h" -#include "Policy/Policy.h" - -SMM_SUPV_SECURE_POLICY_DATA_V1_0 *FirmwarePolicy; - -/** - Check overlap status between two region. - - @param Address1 The start address of region 1. - @param Size1 The size of region 1. - @param Address2 The start address of region 2. - @param Size2 The offset of region 2. - @param IsOverlapping Boolean to return if it's overlap. - - @retval EFI_SUCCESS There aren't any overflow occurred and overlap status have checked. - @retval EFI_SECURITY_VIOLATION There is a overflow occurred. - -**/ -STATIC -EFI_STATUS -OverlapStatus ( - IN UINTN Address1, - IN UINTN Size1, - IN UINTN Address2, - IN UINTN Size2, - OUT BOOLEAN *IsOverlapping - ) -{ - UINTN End1 = Address1 + Size1 - 1; - UINTN End2 = Address2 + Size2 - 1; - - // Potential underflow - if ((Size1 == 0) || (Size2 == 0)) { - return EFI_SECURITY_VIOLATION; - } - - // Overflow - if (End1 < Address1) { - return EFI_SECURITY_VIOLATION; - } - - // Overflow - if (End2 < Address2) { - return EFI_SECURITY_VIOLATION; - } - - if ((Address1 <= End2) && (Address2 <= End1)) { - *IsOverlapping = TRUE; - } else { - *IsOverlapping = FALSE; - } - - return EFI_SUCCESS; -} - -/** - Policy validity check for a given security policy. Check covers policy range - overlap, policy entry header type mismatch, etc. - - @param[in] SmmSecurityPolicy - The address of applied SMM secure policy. - - @retval EFI_SECURITY_VIOLATION The supplied policy failed checking due to - overlapping, type mismatch, etc. - EFI_INVALID_PARAMETER The supplied policy pointer is a null pointer. - EFI_SUCCESS The supplied policy has passed supervisor - checking. -**/ -EFI_STATUS -SecurityPolicyCheck ( - IN SMM_SUPV_SECURE_POLICY_DATA_V1_0 *SmmSecurityPolicy - ) -{ - EFI_STATUS Status; - SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 *MemDescriptors = NULL; - SMM_SUPV_SECURE_POLICY_IO_DESCRIPTOR_V1_0 *IoDescriptors = NULL; - SMM_SUPV_SECURE_POLICY_MSR_DESCRIPTOR_V1_0 *MsrDescriptors = NULL; - SMM_SUPV_SECURE_POLICY_INSTRUCTION_DESCRIPTOR_V1_0 *InstrDescriptors = NULL; - SMM_SUPV_SECURE_POLICY_SAVE_STATE_DESCRIPTOR_V1_0 *SvstDescriptors = NULL; - SMM_SUPV_POLICY_ROOT_V1 *PolicyRoot = NULL; - UINT64 TypeDuplicationFlag = 0; - UINTN Index0; - UINTN Index1; - UINTN Index2; - UINTN TempAddress; - UINTN TempSize; - UINTN TotalScannedSize; - BOOLEAN IsOverlapping; - - DEBUG ((DEBUG_INFO, "%a - Policy overlap check entry ...\n", __FUNCTION__)); - - if (SmmSecurityPolicy == NULL) { - Status = EFI_INVALID_PARAMETER; - goto Exit; - } - - if ((SmmSecurityPolicy->Reserved != 0) && - (SmmSecurityPolicy->Flags != 0) && - (SmmSecurityPolicy->Capabilities != 0)) - { - DEBUG ((DEBUG_ERROR, "%a - Secure policy header has unrecognized bits set.\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - // Keep a total size to indicate all the scanned portions, the final size should match the size from header - TotalScannedSize = sizeof (SMM_SUPV_SECURE_POLICY_DATA_V1_0); - - PolicyRoot = (SMM_SUPV_POLICY_ROOT_V1 *)((UINTN)SmmSecurityPolicy + SmmSecurityPolicy->PolicyRootOffset); - for (Index0 = 0; Index0 < SmmSecurityPolicy->PolicyRootCount; Index0++) { - if (PolicyRoot[Index0].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_IO) { - // IO Policy Overlap Check - if (TypeDuplicationFlag & (BIT0 << SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_IO)) { - DEBUG ((DEBUG_INFO, "%a - Duplicated IO policy root found ...\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - TypeDuplicationFlag |= (BIT0 << SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_IO); - IoDescriptors = (SMM_SUPV_SECURE_POLICY_IO_DESCRIPTOR_V1_0 *)((UINTN)SmmSecurityPolicy + PolicyRoot[Index0].Offset); - for (Index1 = 0; Index1 < PolicyRoot[Index0].Count; Index1++) { - for (Index2 = 0; Index2 < Index1; Index2++) { - TempAddress = IoDescriptors[Index1].IoAddress; - TempSize = IoDescriptors[Index1].LengthOrWidth; - - // Naively iterate through all entries to check overlap - if (IoDescriptors[Index2].Attributes & SECURE_POLICY_RESOURCE_ATTR_STRICT_WIDTH) { - // Strict width entry will only be shadowed by its superset - if ((TempAddress <= IoDescriptors[Index2].IoAddress) && - (TempAddress + TempSize >= (UINT32)IoDescriptors[Index2].IoAddress + IoDescriptors[Index2].LengthOrWidth)) - { - DEBUG ((DEBUG_ERROR, "%a - IO policy strict width overlap check failed\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - } else { - // Otherwise, any overlap will count as policy check failure - Status = OverlapStatus ( - (UINTN)IoDescriptors[Index2].IoAddress, - (UINTN)IoDescriptors[Index2].LengthOrWidth, - TempAddress, - TempSize, - &IsOverlapping - ); - if (EFI_ERROR (Status) || IsOverlapping) { - DEBUG ((DEBUG_ERROR, "%a - IO policy overlap check failed - %r\n", __FUNCTION__, Status)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - } - } - - if (IoDescriptors[Index1].Reserved != 0) { - DEBUG ((DEBUG_ERROR, "%a - IO policy has non zero reserved field.\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - TotalScannedSize += sizeof (SMM_SUPV_SECURE_POLICY_IO_DESCRIPTOR_V1_0); - } - - TotalScannedSize += sizeof (SMM_SUPV_POLICY_ROOT_V1); - } else if (PolicyRoot[Index0].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MEM) { - // Memory Policy Overlap Check - if (TypeDuplicationFlag & (BIT0 << SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MEM)) { - DEBUG ((DEBUG_INFO, "%a - Duplicated Memory policy root found ...\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - TypeDuplicationFlag |= (BIT0 << SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MEM); - MemDescriptors = (SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 *)((UINTN)SmmSecurityPolicy + PolicyRoot[Index0].Offset); - for (Index1 = 0; Index1 < PolicyRoot[Index0].Count; Index1++) { - for (Index2 = 0; Index2 < Index1; Index2++) { - TempAddress = MemDescriptors[Index1].BaseAddress; - TempSize = MemDescriptors[Index1].Size; - - // Naively iterate through all entries to check overlap - Status = OverlapStatus ( - (UINTN)MemDescriptors[Index2].BaseAddress, - (UINTN)MemDescriptors[Index2].Size, - TempAddress, - TempSize, - &IsOverlapping - ); - if (EFI_ERROR (Status) || IsOverlapping) { - DEBUG ((DEBUG_ERROR, "%a - Memory policy overlap check failed - %r\n", __FUNCTION__, Status)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - } - - if (MemDescriptors[Index1].Reserved != 0) { - DEBUG ((DEBUG_ERROR, "%a - Mem policy has non zero reserved field.\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - TotalScannedSize += sizeof (SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0); - } - - TotalScannedSize += sizeof (SMM_SUPV_POLICY_ROOT_V1); - } else if (PolicyRoot[Index0].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MSR) { - // MSR Policy Overlap Check - if (TypeDuplicationFlag & (BIT0 << SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MSR)) { - DEBUG ((DEBUG_INFO, "%a - Duplicated MSR policy root found ...\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - TypeDuplicationFlag |= (BIT0 << SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MSR); - MsrDescriptors = (SMM_SUPV_SECURE_POLICY_MSR_DESCRIPTOR_V1_0 *)((UINTN)SmmSecurityPolicy + PolicyRoot[Index0].Offset); - for (Index1 = 0; Index1 < PolicyRoot[Index0].Count; Index1++) { - for (Index2 = 0; Index2 < Index1; Index2++) { - TempAddress = MsrDescriptors[Index1].MsrAddress; - TempSize = MsrDescriptors[Index1].Length; - - // Naively iterate through all entries to check overlap - Status = OverlapStatus ( - (UINTN)MsrDescriptors[Index2].MsrAddress, - (UINTN)MsrDescriptors[Index2].Length, - TempAddress, - TempSize, - &IsOverlapping - ); - if (EFI_ERROR (Status) || IsOverlapping) { - DEBUG ((DEBUG_ERROR, "%a - MSR policy overlap check failed - %r\n", __FUNCTION__, Status)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - } - - TotalScannedSize += sizeof (SMM_SUPV_SECURE_POLICY_MSR_DESCRIPTOR_V1_0); - } - - TotalScannedSize += sizeof (SMM_SUPV_POLICY_ROOT_V1); - } else if (PolicyRoot[Index0].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_INSTRUCTION) { - // Instruction Policy Duplication Check - if (TypeDuplicationFlag & (BIT0 << SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_INSTRUCTION)) { - DEBUG ((DEBUG_INFO, "%a - Duplicated Instruction policy root found ...\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - TypeDuplicationFlag |= (BIT0 << SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_INSTRUCTION); - InstrDescriptors = (SMM_SUPV_SECURE_POLICY_INSTRUCTION_DESCRIPTOR_V1_0 *)((UINTN)SmmSecurityPolicy + PolicyRoot[Index0].Offset); - for (Index1 = 0; Index1 < PolicyRoot[Index0].Count; Index1++) { - for (Index2 = 0; Index2 < Index1; Index2++) { - // Naively iterate through all entries to check duplication - if (InstrDescriptors[Index1].InstructionIndex == InstrDescriptors[Index2].InstructionIndex) { - DEBUG ((DEBUG_ERROR, "%a - Instruction policy duplication check failed - %r\n", __FUNCTION__, Status)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - } - - if (InstrDescriptors[Index1].Reserved != 0) { - DEBUG ((DEBUG_ERROR, "%a - Instruction policy has non zero reserved field.\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - TotalScannedSize += sizeof (SMM_SUPV_SECURE_POLICY_INSTRUCTION_DESCRIPTOR_V1_0); - } - - TotalScannedSize += sizeof (SMM_SUPV_POLICY_ROOT_V1); - } else if (PolicyRoot[Index0].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_SAVE_STATE) { - // Save State Policy Duplication Check - if (TypeDuplicationFlag & (BIT0 << SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_SAVE_STATE)) { - DEBUG ((DEBUG_INFO, "%a - Duplicated Save state policy root found ...\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - TypeDuplicationFlag |= (BIT0 << SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_SAVE_STATE); - SvstDescriptors = (SMM_SUPV_SECURE_POLICY_SAVE_STATE_DESCRIPTOR_V1_0 *)((UINTN)SmmSecurityPolicy + PolicyRoot[Index0].Offset); - for (Index1 = 0; Index1 < PolicyRoot[Index0].Count; Index1++) { - for (Index2 = 0; Index2 < Index1; Index2++) { - // Naively iterate through all entries to check duplication - // Two policy entries with the same map field, regardless of their attributes, will not be allowed - if (SvstDescriptors[Index1].MapField == SvstDescriptors[Index2].MapField) { - DEBUG ((DEBUG_ERROR, "%a - Save state policy duplication check failed - %r\n", __FUNCTION__, Status)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - } - - // Make sure no write-access related attribute is reported in the policy. This supervisor does not support it. - // Although SMM level 30 specification permits RAX to be written on a trapped IO read, no - // existing implementations require this feature, so it is blocked as well - if (((SvstDescriptors[Index1].Attributes & (SECURE_POLICY_RESOURCE_ATTR_WRITE | SECURE_POLICY_RESOURCE_ATTR_COND_WRITE)) != 0) || - ((SvstDescriptors[Index1].Attributes & (SECURE_POLICY_RESOURCE_ATTR_READ | SECURE_POLICY_RESOURCE_ATTR_COND_READ)) == - (SECURE_POLICY_RESOURCE_ATTR_READ | SECURE_POLICY_RESOURCE_ATTR_COND_READ))) - { - DEBUG (( - DEBUG_ERROR, - "%a - Save state policy has unsupported attributes %x.\n", - __FUNCTION__, - SvstDescriptors[Index1].Attributes - )); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - // Unconditional entries shall not have conditions specified - // Only conditional read is checked here since we do not allow write attributes - if (((SvstDescriptors[Index1].Attributes & SECURE_POLICY_RESOURCE_ATTR_COND_READ) == 0) && - (SvstDescriptors[Index1].AccessCondition != SECURE_POLICY_SVST_UNCONDITIONAL)) - { - DEBUG ((DEBUG_ERROR, "%a - Save state policy has conflicting condition on attributes.\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - if (SvstDescriptors[Index1].Reserved != 0) { - DEBUG ((DEBUG_ERROR, "%a - Save state policy has non zero reserved field.\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - TotalScannedSize += sizeof (SMM_SUPV_SECURE_POLICY_SAVE_STATE_DESCRIPTOR_V1_0); - } - - TotalScannedSize += sizeof (SMM_SUPV_POLICY_ROOT_V1); - } else { - DEBUG ((DEBUG_ERROR, "%a - Unrecognized policy type check %x\n", __FUNCTION__, PolicyRoot[Index0].Type)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - if (!IsZeroBuffer (PolicyRoot[Index0].Reserved, sizeof (PolicyRoot[Index0].Reserved))) { - DEBUG ((DEBUG_ERROR, "%a - Policy root has non zero reserved field.\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - } - - // Legacy Memory Policy Existence Check - if (SmmSecurityPolicy->MemoryPolicyCount != 0) { - DEBUG ((DEBUG_ERROR, "%a - Legacy memory policy detected, not supported!\n", __FUNCTION__)); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - - if (TotalScannedSize != SmmSecurityPolicy->Size) { - DEBUG (( - DEBUG_ERROR, - "%a - Unrecognized bytes detected in the policy (expecting 0x%x, has 0x%x), not allowed!\n", - __FUNCTION__, - TotalScannedSize, - SmmSecurityPolicy->Size - )); - Status = EFI_SECURITY_VIOLATION; - goto Exit; - } - -Exit: - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Policy overlap check failed - %r\n", __FUNCTION__, Status)); - ASSERT_EFI_ERROR (Status); - } - - DEBUG ((DEBUG_INFO, "%a - Policy overlap check exit ...\n", __FUNCTION__)); - return Status; -} - -/** - Dump the smm policy data. -**/ -VOID -DumpSmmPolicyData ( - SMM_SUPV_SECURE_POLICY_DATA_V1_0 *Data - ) -{ - UINT32 i; - UINT32 j; - - SMM_SUPV_POLICY_ROOT_V1 *PolicyRoot; - SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 *MemoryPolicy; - SMM_SUPV_SECURE_POLICY_IO_DESCRIPTOR_V1_0 *IoPolicy; - SMM_SUPV_SECURE_POLICY_MSR_DESCRIPTOR_V1_0 *MsrPolicy; - SMM_SUPV_SECURE_POLICY_INSTRUCTION_DESCRIPTOR_V1_0 *InstructionPolicy; - SMM_SUPV_SECURE_POLICY_SAVE_STATE_DESCRIPTOR_V1_0 *SaveStatePolicy; - - DEBUG ((DEBUG_INFO, "SMM_SUPV_SECURE_POLICY_DATA_V1_0:\n")); - DEBUG ((DEBUG_INFO, "Version Major:%x\n", Data->VersionMajor)); - DEBUG ((DEBUG_INFO, "Version Minor:%x\n", Data->VersionMinor)); - DEBUG ((DEBUG_INFO, "Size:0x%x\n", Data->Size)); - DEBUG ((DEBUG_INFO, "MemoryPolicyOffset:0x%x\n", Data->MemoryPolicyOffset)); - DEBUG ((DEBUG_INFO, "MemoryPolicyCount:0x%x\n", Data->MemoryPolicyCount)); - DEBUG ((DEBUG_INFO, "Flags:%x\n", Data->Flags)); - DEBUG ((DEBUG_INFO, "Capabilities:%x\n", Data->Capabilities)); - DEBUG ((DEBUG_INFO, "PolicyRootOffset:0x%x\n", Data->PolicyRootOffset)); - DEBUG ((DEBUG_INFO, "PolicyRootCount:0x%x\n", Data->PolicyRootCount)); - - PolicyRoot = (SMM_SUPV_POLICY_ROOT_V1 *)((UINTN)Data + Data->PolicyRootOffset); - // Iterate through each policy root - for (i = 0; i < Data->PolicyRootCount; i++) { - DEBUG ((DEBUG_INFO, "Policy Root:\n")); - DEBUG ((DEBUG_INFO, " Version: %x\n", PolicyRoot[i].Version)); - DEBUG ((DEBUG_INFO, " PolicyRootSize: %x\n", PolicyRoot[i].PolicyRootSize)); - DEBUG ((DEBUG_INFO, " Type: %x\n", PolicyRoot[i].Type)); - DEBUG ((DEBUG_INFO, " Offset: %x\n", PolicyRoot[i].Offset)); - DEBUG ((DEBUG_INFO, " Count: %x\n", PolicyRoot[i].Count)); - DEBUG ((DEBUG_INFO, " AccessAttr: %a\n", (PolicyRoot[i].AccessAttr == SMM_SUPV_ACCESS_ATTR_ALLOW) ? "ALLOW" : "DENY")); - // Iterate through each policy descriptor described by this policy root - for (j = 0; j < PolicyRoot[i].Count; j++) { - if (PolicyRoot[i].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MEM) { - // Dump Memory Policy - MemoryPolicy = (SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 *)((UINTN)Data + PolicyRoot[i].Offset); - DumpMemPolicyEntry (&MemoryPolicy[j]); - } else if (PolicyRoot[i].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_IO) { - // Dump IoPolicy - IoPolicy = (SMM_SUPV_SECURE_POLICY_IO_DESCRIPTOR_V1_0 *)((UINTN)Data + PolicyRoot[i].Offset); - DEBUG (( - DEBUG_INFO, - "IO: [%lx-%lx] %a %a\n", \ - IoPolicy[j].IoAddress, \ - IoPolicy[j].IoAddress + IoPolicy[j].LengthOrWidth - 1, \ - (IoPolicy[j].Attributes & SECURE_POLICY_RESOURCE_ATTR_READ) ? "R" : ".", \ - (IoPolicy[j].Attributes & SECURE_POLICY_RESOURCE_ATTR_WRITE) ? "W" : "." \ - )); - } else if (PolicyRoot[i].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MSR) { - // Dump MsrPolicy - MsrPolicy = (SMM_SUPV_SECURE_POLICY_MSR_DESCRIPTOR_V1_0 *)((UINTN)Data + PolicyRoot[i].Offset); - DEBUG (( - DEBUG_INFO, - "MSR: [%lx-%lx] %a %a\n", \ - MsrPolicy[j].MsrAddress, \ - MsrPolicy[j].MsrAddress + MsrPolicy[j].Length - 1, \ - (MsrPolicy[j].Attributes & SECURE_POLICY_RESOURCE_ATTR_READ) ? "R" : ".", \ - (MsrPolicy[j].Attributes & SECURE_POLICY_RESOURCE_ATTR_WRITE) ? "W" : "." \ - )); - } else if (PolicyRoot[i].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_INSTRUCTION) { - // Dump InstructionPolicy - InstructionPolicy = (SMM_SUPV_SECURE_POLICY_INSTRUCTION_DESCRIPTOR_V1_0 *)((UINTN)Data + PolicyRoot[i].Offset); - DEBUG (( - DEBUG_INFO, - "INSTRUCTION: [%lx] %a\n", \ - InstructionPolicy[j].InstructionIndex, \ - (InstructionPolicy[j].Attributes & SECURE_POLICY_RESOURCE_ATTR_EXECUTE) ? "X" : "." - )); - } else if (PolicyRoot[i].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_SAVE_STATE) { - // Dump SaveStatePolicy - SaveStatePolicy = (SMM_SUPV_SECURE_POLICY_SAVE_STATE_DESCRIPTOR_V1_0 *)((UINTN)Data + PolicyRoot[i].Offset); - DEBUG (( - DEBUG_INFO, - "SAVESTATE: [%lx] %x %a\n", \ - SaveStatePolicy[j].MapField, \ - (SaveStatePolicy[j].Attributes), \ - ((SaveStatePolicy[j].AccessCondition == SECURE_POLICY_SVST_UNCONDITIONAL) ? "Unconditional" : - ((SaveStatePolicy[j].AccessCondition == SECURE_POLICY_SVST_CONDITION_IO_RD) ? "IoRead" : "IoWrite")) - )); - } else { - DEBUG ((DEBUG_ERROR, "Unrecognized policy root type found %x, bailing!!!\n", PolicyRoot[i].Type)); - return; - } - } - } -} - -/** - Routine for initializing policy data provided by firmware. - - @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. - @retval Errors The supervisor is unable to locate or protect the policy from firmware. - -**/ -EFI_STATUS -InitializePolicy ( - VOID - ) -{ - EFI_STATUS Status; - EFI_FFS_FILE_HEADER *FileHeader; - VOID *SectionData; - UINTN SectionDataSize; - UINTN PolicySize; - - FirmwarePolicy = NULL; - - // - // First try to find the policy file based on the GUID specified. - // - FileHeader = NULL; - do { - Status = FfsFindNextFile ( - EFI_FV_FILETYPE_FREEFORM, - (EFI_FIRMWARE_VOLUME_HEADER *)gMmCorePrivate.StandaloneBfvAddress, - &FileHeader - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "[%a] Failed to locate firmware policy file from given FV - %r\n", - __FUNCTION__, - Status - )); - break; - } - - if (!CompareGuid (&FileHeader->Name, &gMmSupervisorPolicyFileGuid)) { - continue; - } - - DEBUG (( - DEBUG_INFO, - "[%a] Discovered policy file in FV at 0x%p.\n", - __FUNCTION__, - FileHeader - )); - - Status = FfsFindSectionData ( - EFI_SECTION_RAW, - FileHeader, - &SectionData, - &SectionDataSize - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "[%a] Failed to find raw section from discovered policy file - %r\n", - __FUNCTION__, - Status - )); - break; - } - - PolicySize = ((SMM_SUPV_SECURE_POLICY_DATA_V1_0 *)SectionData)->Size; - if (PolicySize > SectionDataSize) { - DEBUG (( - DEBUG_ERROR, - "[%a] Policy data size 0x%x > blob size 0x%x.\n", - __FUNCTION__, - PolicySize, - SectionDataSize - )); - Status = EFI_BAD_BUFFER_SIZE; - break; - } - - FirmwarePolicy = AllocateAlignedPages (EFI_SIZE_TO_PAGES (PolicySize), EFI_PAGE_SIZE); - if (FirmwarePolicy == NULL) { - Status = EFI_OUT_OF_RESOURCES; - DEBUG (( - DEBUG_ERROR, - "[%a] Cannot allocate page for firmware provided policy - %r\n", - __FUNCTION__, - Status - )); - break; - } - - CopyMem (FirmwarePolicy, SectionData, PolicySize); - - DEBUG_CODE_BEGIN (); - DumpSmmPolicyData (FirmwarePolicy); - DEBUG_CODE_END (); - - // We found one valid firmware policy, do not need to proceed further on this FV. - break; - } while (TRUE); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Unable to locate a valid firmware policy from given FV, bail here - %r\n", __FUNCTION__, Status)); - ASSERT_EFI_ERROR (Status); - goto Done; - } - - // Prepare the buffer for Mem policy snapshot, it will be compared against when non-MM entity requested - Status = AllocateMemForPolicySnapshot (); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Failed to allocate buffer for memory policy snapshot - %r\n", __FUNCTION__, Status)); - ASSERT_EFI_ERROR (Status); - goto Done; - } - - Status = SecurityPolicyCheck (FirmwarePolicy); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Policy check failed on policy blob from firmware - %r\n", __FUNCTION__, Status)); - ASSERT_EFI_ERROR (Status); - goto Done; - } - -Done: - return Status; -} diff --git a/MmSupervisorPkg/Core/Policy/MemPolicy.c b/MmSupervisorPkg/Core/Policy/MemPolicy.c deleted file mode 100644 index 3ee87bea..00000000 --- a/MmSupervisorPkg/Core/Policy/MemPolicy.c +++ /dev/null @@ -1,672 +0,0 @@ -/** @file -Implementation of SMM policy related routine. - -Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
-Copyright (c) 2020, AMD Incorporated. All rights reserved.
-Copyright (c) Microsoft Corporation. -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include - -#include - -#include "MmSupervisorCore.h" -#include "Mem/Mem.h" -#include "Policy/Policy.h" - -#define MEM_POLICY_SNAPSHOT_SIZE 0x400 // 1K should be more than enough to describe allowed non-MMRAM regions - -SMM_SUPV_SECURE_POLICY_DATA_V1_0 *MemPolicySnapshot; - -#define MEM_DESC_UNINIT_BASEADDR 0xDEADBEEF - -#pragma pack(1) - -// -// Page Table Entry 4KB -// -typedef union { - struct { - UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User - UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Dirty : 1; // 0 = Not Dirty, 1 = written by processor on access to page - UINT64 PS : 1; // In PDPE, PDE present PS bit, can be used determine if it is 1G or 2M page - UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write - UINT64 Available : 3; // Available for use by system software - UINT64 PageTableBaseAddress : 40; // Page Table Base Address - UINT64 AvailableHigh : 11; // Available for use by system software - UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution - } Bits; - UINT64 Uint64; -} PAGE_TABLE_ENTRY; - -#pragma pack() - -/** - Update the policy memory description. -**/ -STATIC -VOID -UpdateMemoryDesc ( - SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 **pMemoryPolicy, - UINT32 *pMemoryPolicyCount, - UINT32 MemoryAttr, - UINT64 PageTableBaseAddress, - UINT64 Size - ) -{ - SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 *MemoryPolicy; - - MemoryPolicy = *pMemoryPolicy; - // DEBUG ((DEBUG_INFO, "UpdateMemoryDesc %x %x \n", MemoryPolicy, pMemoryPolicyCount)); - // This is the 1st record - if (MemoryPolicy->BaseAddress == MEM_DESC_UNINIT_BASEADDR) { - MemoryPolicy->BaseAddress = PageTableBaseAddress; - MemoryPolicy->Size = Size; - MemoryPolicy->MemAttributes = MemoryAttr; - } else { - // Check if the continual address of Current memory policy - if ((PageTableBaseAddress == MemoryPolicy->BaseAddress + MemoryPolicy->Size) && - (MemoryAttr == MemoryPolicy->MemAttributes)) - { - MemoryPolicy->Size += Size; - } else { - MemoryPolicy++; - MemoryPolicy->BaseAddress = PageTableBaseAddress; - MemoryPolicy->Size = Size; - MemoryPolicy->MemAttributes = MemoryAttr; - MemoryPolicy->Reserved = 0; - *pMemoryPolicyCount += 1; - *pMemoryPolicy = MemoryPolicy; - } - } -} - -// comment to disable debug print -// #define PAGE_TBL_PRINT_EN - -#ifdef PAGE_TBL_PRINT_EN -#define PAGE_TBL_PRINT(Expression) DEBUG (Expression) -#else -#define PAGE_TBL_PRINT(Expression) -#endif - -/* - Generate Memory policy DENIAL DESCRIPTORs by traverse pagetables - Shadow current pagetable if IsShadow set - if input Cr3 is zero, check the real HW register - - @retval EFI_SUCCESS Execute operation successfully - @retval EFI_OUT_OF_RESOURCES MemoryPolicySize is too small to hold all memory policy - @retval EFI_UNSUPPORTED Current register setting doesn't support page mode, if input CR3 is no-zero -*/ -STATIC -EFI_STATUS -GenMemPolicyAndShadowPageTable ( - IN UINT64 Cr3, - IN OUT VOID *MemoryPolicyPtr, - IN UINTN MemoryPolicySize, - IN OUT UINT32 *MemoryPolicyCount - ) -{ - MSR_IA32_EFER_REGISTER MsrEfer; - IA32_CR0 Cr0; - UINT64 PML4Base; - UINT32 i, j, k, l; - PAGE_TABLE_ENTRY *PML4Table; - PAGE_TABLE_ENTRY *PDPETable; - PAGE_TABLE_ENTRY *PDETable; - PAGE_TABLE_ENTRY *PTETable; - UINT64 PageTableBaseAddress; - SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 *MemoryPolicy; - UINT32 PML4MemoryAttr; - UINT32 PDPEMemoryAttr; - UINT32 PDEMemoryAttr; - UINT32 MemoryAttr; - UINTN L4PageNum; - UINTN L3PageNum; - UINTN L2PageNum; - UINTN L1PageNum; - UINTN MemPolicyBoundary; - - MemPolicyBoundary = (UINTN)MemoryPolicyPtr + MemoryPolicySize; - *MemoryPolicyCount = 1; - L4PageNum = 0; - L3PageNum = 0; - L2PageNum = 0; - L1PageNum = 0; - MemoryPolicy = MemoryPolicyPtr; - MemoryPolicy->BaseAddress = MEM_DESC_UNINIT_BASEADDR; - - DEBUG ((DEBUG_INFO, "GenMemPolicyAndShadowPageTable, MemoryPolicyPtr:%lx, MemoryPolicySize:%lx\n", (UINTN)MemoryPolicyPtr, MemoryPolicySize)); - // Code to traverse SMM page table to generate SMM policy structure - if (Cr3 == 0) { - // Only support long page table - // Check if long mode - MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); - DEBUG ((DEBUG_INFO, "EFER.NXE = %x\n", MsrEfer.Bits.NXE)); - if ((MsrEfer.Bits.LME == 0) || (MsrEfer.Bits.LMA == 0)) { - DEBUG ((DEBUG_ERROR, "EFER.LMA ==0 || EFER.LME == 0, exit\n")); - return EFI_UNSUPPORTED; - } - - // Check if Page enabled - Cr0.UintN = AsmReadCr0 (); - if (Cr0.Bits.PG == 0) { - DEBUG ((DEBUG_ERROR, "Cr0.Bits.PG == 0, exit\n")); - return EFI_UNSUPPORTED; - } - - // Assuming CR0.WP enabled - if (Cr0.Bits.WP == 0) { - DEBUG ((DEBUG_ERROR, "Cr0.Bits.WP == 0, exit\n")); - return EFI_UNSUPPORTED; - } - - // Get PML4 base from CR3 register - PML4Base = AsmReadCr3 () & 0x000FFFFFFFFFF000ull; - } else { - // Get PML4 base from input - PML4Base = Cr3 & 0x000FFFFFFFFFF000ull; - } - - DEBUG ((DEBUG_INFO, "PML4Base = 0x%x\n", PML4Base)); - PML4Table = (PAGE_TABLE_ENTRY *)PML4Base; - L4PageNum++; - // Loop 512 PML4 entries - for (i = 0; i < 512; i++) { - PAGE_TBL_PRINT ((DEBUG_INFO, "PML4[%d] = 0x%Lx \n", i, PML4Table[i].Uint64)); - // If present not set, skip this page table entry - if (PML4Table[i].Bits.Present == 0) { - continue; - } - - PAGE_TBL_PRINT ( - (DEBUG_INFO, "P:%x R/W:%x U/S:%x PWT:%x PCD:%x A:%x D:%x PS:%x G:%x NX:%x\n", \ - PML4Table[i].Bits.Present, \ - PML4Table[i].Bits.ReadWrite, \ - PML4Table[i].Bits.UserSupervisor, \ - PML4Table[i].Bits.WriteThrough, \ - PML4Table[i].Bits.CacheDisabled, \ - PML4Table[i].Bits.Accessed, \ - PML4Table[i].Bits.Dirty, \ - PML4Table[i].Bits.PS, \ - PML4Table[i].Bits.Global, \ - PML4Table[i].Bits.Nx - ) - ); - PML4MemoryAttr = 0; - if (PML4Table[i].Bits.ReadWrite == 1) { - PML4MemoryAttr |= (SECURE_POLICY_RESOURCE_ATTR_WRITE | SECURE_POLICY_RESOURCE_ATTR_READ); - } else { - PML4MemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_READ; - } - - if (PML4Table[i].Bits.Nx == 0) { - PML4MemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_EXECUTE; - } - - PDPETable = (PAGE_TABLE_ENTRY *)(PML4Table[i].Uint64 & 0x000FFFFFFFFFF000ull); - L3PageNum++; - // Loop 512 PDPE entries - for (j = 0; j < 512; j++) { - // If present not set, skip this page table entry - if (PDPETable[j].Bits.Present == 0) { - continue; - } - - PAGE_TBL_PRINT ((DEBUG_INFO, "\tPDPE[%d] = 0x%x ", j, PDPETable[j].Uint64)); - PAGE_TBL_PRINT ( - (DEBUG_INFO, "P:%x R/W:%x U/S:%x PWT:%x PCD:%x A:%x D:%x PS:%x G:%x NX:%x\n", \ - PDPETable[j].Bits.Present, \ - PDPETable[j].Bits.ReadWrite, \ - PDPETable[j].Bits.UserSupervisor, \ - PDPETable[j].Bits.WriteThrough, \ - PDPETable[j].Bits.CacheDisabled, \ - PDPETable[j].Bits.Accessed, \ - PDPETable[j].Bits.Dirty, \ - PDPETable[j].Bits.PS, \ - PDPETable[j].Bits.Global, \ - PDPETable[j].Bits.Nx \ - ) - ); - PDPEMemoryAttr = 0; - if (PDPETable[j].Bits.ReadWrite == 1) { - PDPEMemoryAttr |= (SECURE_POLICY_RESOURCE_ATTR_WRITE | SECURE_POLICY_RESOURCE_ATTR_READ); - } else { - PDPEMemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_READ; - } - - if (PDPETable[j].Bits.Nx == 0) { - PDPEMemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_EXECUTE; - } - - // PS resent in the lowest level of the page-translation - if (PDPETable[j].Bits.PS == 1) { - // 1G Table reached - PageTableBaseAddress = PDPETable[j].Uint64 & PAGING_1G_ADDRESS_MASK_64; - if (PDPETable[j].Bits.UserSupervisor == 0) { - DEBUG ((DEBUG_VERBOSE, "CPL0 ADDR[%lx-%lx]\n", PageTableBaseAddress, PageTableBaseAddress+ 0x40000000ull -1)); - } - - PAGE_TBL_PRINT ((DEBUG_INFO, "ADDR[%lx-%lx]", PageTableBaseAddress, PageTableBaseAddress+ 0x40000000ull -1)); - PAGE_TBL_PRINT ( - (DEBUG_INFO, "P:%x R/W:%x U/S:%x PWT:%x PCD:%x A:%x D:%x PS:%x G:%x NX:%x\n", \ - PDPETable[j].Bits.Present, \ - PDPETable[j].Bits.ReadWrite, \ - PDPETable[j].Bits.UserSupervisor, \ - PDPETable[j].Bits.WriteThrough, \ - PDPETable[j].Bits.CacheDisabled, \ - PDPETable[j].Bits.Accessed, \ - PDPETable[j].Bits.Dirty, \ - PDPETable[j].Bits.PS, \ - PDPETable[j].Bits.Global, \ - PDPETable[j].Bits.Nx \ - ) - ); - if (IsBufferInsideMmram (PageTableBaseAddress, 0x40000000ull)) { - // Do not report if this region is fully inside MMRAM, meaning we still report the page if the page is at the limbo - continue; - } - - // Set to R/W, execute enable as default - MemoryAttr = 0; - if (PDPETable[j].Bits.Present == 1) { - MemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_EXECUTE; - MemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_READ; - MemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_WRITE; - } - - // For new struct, upper table R/W allowance can be inherited - MemoryAttr &= PDPEMemoryAttr; - MemoryAttr &= PML4MemoryAttr; - UpdateMemoryDesc (&MemoryPolicy, MemoryPolicyCount, MemoryAttr, PageTableBaseAddress, 0x40000000ull); - ASSERT ((UINTN)MemoryPolicy < MemPolicyBoundary); - if ((UINTN)MemoryPolicy >= MemPolicyBoundary) { - return EFI_OUT_OF_RESOURCES; - } - - continue; - } - - PDETable = (PAGE_TABLE_ENTRY *)(PDPETable[j].Uint64 & 0x000FFFFFFFFFF000ull); - L2PageNum++; - // Loop 512 PDE entries - for (k = 0; k < 512; k++) { - // If present not set, skip this page table entry - if (PDETable[k].Bits.Present == 0) { - continue; - } - - PAGE_TBL_PRINT ((DEBUG_INFO, "\t\tPDE[%d] = 0x%x ", k, PDETable[k].Uint64)); - PAGE_TBL_PRINT ( - (DEBUG_INFO, "P:%x R/W:%x U/S:%x PWT:%x PCD:%x A:%x D:%x PS:%x G:%x NX:%x\n", \ - PDETable[k].Bits.Present, \ - PDETable[k].Bits.ReadWrite, \ - PDETable[k].Bits.UserSupervisor, \ - PDETable[k].Bits.WriteThrough, \ - PDETable[k].Bits.CacheDisabled, \ - PDETable[k].Bits.Accessed, \ - PDETable[k].Bits.Dirty, \ - PDETable[k].Bits.PS, \ - PDETable[k].Bits.Global, \ - PDETable[k].Bits.Nx - ) - ); - PDEMemoryAttr = 0; - if (PDETable[k].Bits.ReadWrite == 1) { - PDEMemoryAttr |= (SECURE_POLICY_RESOURCE_ATTR_WRITE | SECURE_POLICY_RESOURCE_ATTR_READ); - } else { - PDEMemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_READ; - } - - if (PDETable[k].Bits.Nx == 0) { - PDEMemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_EXECUTE; - } - - // PS resent in the lowest level of the page-translation - if (PDETable[k].Bits.PS == 1) { - // 2M Table reached - PageTableBaseAddress = PDETable[k].Uint64 & PAGING_2M_ADDRESS_MASK_64; - if (PDETable[k].Bits.UserSupervisor == 0) { - DEBUG ((DEBUG_VERBOSE, "CPL0 ADDR[%lx-%lx]\n", PageTableBaseAddress, PageTableBaseAddress+ 0x200000ull -1)); - } - - PAGE_TBL_PRINT ((DEBUG_INFO, "ADDR[%lx-%lx]", PageTableBaseAddress, PageTableBaseAddress+ 0x200000ull - 1)); - PAGE_TBL_PRINT ( - (DEBUG_INFO, "P:%x R/W:%x U/S:%x PWT:%x PCD:%x A:%x D:%x PS:%x G:%x NX:%x\n", \ - PDETable[k].Bits.Present, \ - PDETable[k].Bits.ReadWrite, \ - PDETable[k].Bits.UserSupervisor, \ - PDETable[k].Bits.WriteThrough, \ - PDETable[k].Bits.CacheDisabled, \ - PDETable[k].Bits.Accessed, \ - PDETable[k].Bits.Dirty, \ - PDETable[k].Bits.PS, \ - PDETable[k].Bits.Global, \ - PDETable[k].Bits.Nx - ) - ); - if (IsBufferInsideMmram (PageTableBaseAddress, 0x200000ull)) { - // Do not report if this region is fully inside MMRAM, meaning we still report the page if the page is at the limbo - continue; - } - - // Set to R/W, execute enable as default - MemoryAttr = 0; - if (PDETable[k].Bits.Present == 1) { - MemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_EXECUTE; - MemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_READ; - MemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_WRITE; - } - - // For new struct, upper table R/W allowance can be inherited - MemoryAttr &= PDEMemoryAttr; - MemoryAttr &= PDPEMemoryAttr; - MemoryAttr &= PML4MemoryAttr; - UpdateMemoryDesc (&MemoryPolicy, MemoryPolicyCount, MemoryAttr, PageTableBaseAddress, 0x200000ull); - ASSERT ((UINTN)MemoryPolicy < MemPolicyBoundary); - if ((UINTN)MemoryPolicy >= MemPolicyBoundary) { - return EFI_OUT_OF_RESOURCES; - } - - continue; - } - - L1PageNum++; - PTETable = (PAGE_TABLE_ENTRY *)(PDETable[k].Uint64 & 0x000FFFFFFFFFF000ull); - // Loop 512 PTE entries - for (l = 0; l < 512; l++) { - // If present not set, skip this page table entry - if (PTETable[l].Bits.Present == 0) { - continue; - } - - // 4K Table reached - PageTableBaseAddress = PTETable[l].Uint64 & PAGING_4K_ADDRESS_MASK_64; - if (PTETable[l].Bits.UserSupervisor == 0) { - DEBUG ((DEBUG_VERBOSE, "CPL0 ADDR[%lx-%lx]\n", PageTableBaseAddress, PageTableBaseAddress+ 0x1000ull -1)); - } - - PAGE_TBL_PRINT ((DEBUG_INFO, "ADDR[%lx-%lx]", PageTableBaseAddress, PageTableBaseAddress+ 0x1000ull -1)); - PAGE_TBL_PRINT ( - (DEBUG_INFO, "P:%x R/W:%x U/S:%x PWT:%x PCD:%x A:%x D:%x G:%x NX:%x\n", \ - PTETable[l].Bits.Present, \ - PTETable[l].Bits.ReadWrite, \ - PTETable[l].Bits.UserSupervisor, \ - PTETable[l].Bits.WriteThrough, \ - PTETable[l].Bits.CacheDisabled, \ - PTETable[l].Bits.Accessed, \ - PTETable[l].Bits.Dirty, \ - PTETable[l].Bits.Global, \ - PTETable[l].Bits.Nx - ) - ); - if (IsBufferInsideMmram (PageTableBaseAddress, 0x1000ull)) { - // Do not report if this region is fully inside MMRAM, meaning we still report the page if the page is at the limbo - continue; - } - - // Set to R/W, execute enable as default - MemoryAttr = 0; - if (PTETable[l].Bits.ReadWrite == 1) { - MemoryAttr |= (SECURE_POLICY_RESOURCE_ATTR_WRITE | SECURE_POLICY_RESOURCE_ATTR_READ); - } else { - MemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_READ; - } - - if (PTETable[l].Bits.Present == 1) { - if (PTETable[l].Bits.Nx == 0) { - MemoryAttr |= SECURE_POLICY_RESOURCE_ATTR_EXECUTE; - } - } else { - MemoryAttr = 0; - } - - // For new struct, upper table R/W allowance can be inherited - MemoryAttr &= PDEMemoryAttr; - MemoryAttr &= PDPEMemoryAttr; - MemoryAttr &= PML4MemoryAttr; - UpdateMemoryDesc (&MemoryPolicy, MemoryPolicyCount, MemoryAttr, PageTableBaseAddress, 0x1000ull); - ASSERT ((UINTN)MemoryPolicy < MemPolicyBoundary); - if ((UINTN)MemoryPolicy >= MemPolicyBoundary) { - return EFI_OUT_OF_RESOURCES; - } - } // for (l = 0; l < 512; l++) - } // for (k = 0; k < 512; k++) - } - } - - DEBUG ((DEBUG_INFO, "== L4PageNum: %d, L3PageNum: %d, L2PageNum: %d, L1PageNum: %d ==\n", L4PageNum, L3PageNum, L2PageNum, L1PageNum)); - - return EFI_SUCCESS; -} - -/** - Dump a single memory policy data. -**/ -VOID -DumpMemPolicyEntry ( - SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 *MemoryPolicy - ) -{ - if (MemoryPolicy == NULL) { - DEBUG ((DEBUG_INFO, "%a Received null input pointer!\n", __FUNCTION__)); - ASSERT (FALSE); - return; - } - - DEBUG (( - DEBUG_INFO, - "V1.0 MEM: [%lx-%lx] %a %a %a\n", \ - MemoryPolicy->BaseAddress, \ - MemoryPolicy->BaseAddress + MemoryPolicy->Size -1, \ - (MemoryPolicy->MemAttributes & SECURE_POLICY_RESOURCE_ATTR_READ) ? "R" : ".", \ - (MemoryPolicy->MemAttributes & SECURE_POLICY_RESOURCE_ATTR_WRITE) ? "W" : ".", \ - (MemoryPolicy->MemAttributes & SECURE_POLICY_RESOURCE_ATTR_EXECUTE) ? "X" : "." - )); -} - -/** - Helper function that populates memory policy on demands. - - @param[in] SmmPolicyBuffer Input buffer points to the entire v1.0 policy. - @param[in] Cr3 CR3 value to be converted, if input is zero, check the real HW register. - - @param[in] CpuIndex Logical number assigned to CPU. -**/ -EFI_STATUS -EFIAPI -PopulateMemoryPolicyEntries ( - IN SMM_SUPV_SECURE_POLICY_DATA_V1_0 *SmmPolicyBuffer, - IN UINT64 MaxPolicySize - ) -{ - SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 *MemoryPolicy; - SMM_SUPV_POLICY_ROOT_V1 *PolicyRoot; - UINTN MemoryPolicySize; - UINTN i; - EFI_STATUS Status; - - if (SmmPolicyBuffer == NULL) { - Status = EFI_INVALID_PARAMETER; - DEBUG ((DEBUG_ERROR, "%a Incoming policy buffer is null pointer.\n", __FUNCTION__)); - goto Exit; - } - - // IO and MSR policies are populated during report DRTM info time, - // Here just append MemPolicy to the end of static table. - PolicyRoot = (SMM_SUPV_POLICY_ROOT_V1 *)((UINTN)SmmPolicyBuffer + SmmPolicyBuffer->PolicyRootOffset); - for (i = 0; i < SmmPolicyBuffer->PolicyRootCount; i++) { - if (PolicyRoot[i].Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MEM) { - PolicyRoot = PolicyRoot + i; - break; - } - } - - if (i >= SmmPolicyBuffer->PolicyRootCount) { - // TODO: Do we want to add handling here? - // Something is wrong, there is not placeholder left for memory type, do not want to handle it... - DEBUG ((DEBUG_ERROR, "%a Incoming policy buffer does not contain memory type policy root.\n", __FUNCTION__)); - Status = EFI_NOT_FOUND; - goto Exit; - } - - // Init PolicyRoot->Offset field - PolicyRoot->AccessAttr = SMM_SUPV_ACCESS_ATTR_ALLOW; - if (PolicyRoot->Offset == 0) { - // Only populate the offset if not already set - PolicyRoot->Offset = SmmPolicyBuffer->Size; - } - - PolicyRoot->PolicyRootSize = sizeof (SMM_SUPV_POLICY_ROOT_V1); - // This is not needed with our check above - // PolicyRoot->Type = SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MEM; - PolicyRoot->Version = 1; - MemoryPolicy = (SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 *)((UINTN)SmmPolicyBuffer + PolicyRoot->Offset); - MemoryPolicySize = MaxPolicySize - PolicyRoot->Offset - 1; - // Generate Policy of current Pagetable - Status = GenMemPolicyAndShadowPageTable (0, MemoryPolicy, MemoryPolicySize, &PolicyRoot->Count); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Fail to GenMemPolicyAndShadowPageTable for non-legacy structures %r\n", __FUNCTION__, Status)); - goto Exit; - } - - SmmPolicyBuffer->Size = PolicyRoot->Offset + (sizeof (SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0) * PolicyRoot->Count); - - SmmPolicyBuffer->MemoryPolicyCount = 0; - -Exit: - return Status; -} - -/** - Compare memory policy in two SmmPolicy. - - @param SmmPolicyData1 The first data to compare. - @param SmmPolicyData2 The second data to compare. - - @retval FALSE If two memory policy not identical. - -**/ -BOOLEAN -CompareMemoryPolicy ( - SMM_SUPV_SECURE_POLICY_DATA_V1_0 *SmmPolicyData1, - SMM_SUPV_SECURE_POLICY_DATA_V1_0 *SmmPolicyData2 - ) -{ - UINTN MemoryPolicySize; - UINT8 *SmmMemPolicy1 = NULL; - UINT8 *SmmMemPolicy2 = NULL; - SMM_SUPV_POLICY_ROOT_V1 *PolicyRoot1 = NULL; - SMM_SUPV_POLICY_ROOT_V1 *PolicyRoot2 = NULL; - UINTN i; - - if ((SmmPolicyData1 == NULL) || (SmmPolicyData2 == NULL)) { - return FALSE; - } - - // Locate memory descriptors first - for (i = 0; i < SmmPolicyData1->PolicyRootCount; i++) { - PolicyRoot1 = &((SMM_SUPV_POLICY_ROOT_V1 *)((UINTN)SmmPolicyData1 + SmmPolicyData1->PolicyRootOffset))[i]; - if (PolicyRoot1->Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MEM) { - // Here we found it - SmmMemPolicy1 = (UINT8 *)SmmPolicyData1 + PolicyRoot1->Offset; - break; - } - } - - for (i = 0; i < SmmPolicyData2->PolicyRootCount; i++) { - PolicyRoot2 = &((SMM_SUPV_POLICY_ROOT_V1 *)((UINTN)SmmPolicyData2 + SmmPolicyData2->PolicyRootOffset))[i]; - if (PolicyRoot2->Type == SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MEM) { - // Here we found it - SmmMemPolicy2 = (UINT8 *)SmmPolicyData2 + PolicyRoot2->Offset; - break; - } - } - - if ((SmmMemPolicy1 == NULL) || (SmmMemPolicy2 == NULL) || - (PolicyRoot1 == NULL) || (PolicyRoot2 == NULL) || - (PolicyRoot1->Version != PolicyRoot2->Version) || - (PolicyRoot1->PolicyRootSize != PolicyRoot2->PolicyRootSize) || - (PolicyRoot1->AccessAttr != PolicyRoot2->AccessAttr) || - (PolicyRoot1->Count != PolicyRoot2->Count)) - { - return FALSE; - } - - MemoryPolicySize = sizeof (SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0) * PolicyRoot1->Count; - SmmMemPolicy1 = (UINT8 *)SmmPolicyData1 + PolicyRoot1->Offset; - SmmMemPolicy2 = (UINT8 *)SmmPolicyData2 + PolicyRoot2->Offset; - if (CompareMem (SmmMemPolicy1, SmmMemPolicy2, MemoryPolicySize) == 0) { - return TRUE; // Memory Policy Identical - } - - return FALSE; -} - -/** - Prepare a snapshot of memory policy, this will be compared against the one generated when requested. - - @retval EFI_SUCCESS The security policy is successfully gathered. - @retval EFI_NOT_STARTED No memory policy snapshot buffer prepared. - @retval Errors Other error during populating memory errors. -**/ -EFI_STATUS -PrepareMemPolicySnapshot ( - VOID - ) -{ - SMM_SUPV_POLICY_ROOT_V1 *PolicyRoot; - EFI_STATUS Status; - - if (MemPolicySnapshot == NULL) { - Status = EFI_NOT_STARTED; - goto Done; - } - - // Use SmmTempPolicyData as temp buffer to hold memory policy data - ZeroMem (MemPolicySnapshot, MEM_POLICY_SNAPSHOT_SIZE); - - // First, we populate the bare minimal content for policy root as a kick starter - PolicyRoot = (SMM_SUPV_POLICY_ROOT_V1 *)(MemPolicySnapshot + 1); - MemPolicySnapshot->PolicyRootCount = 1; - MemPolicySnapshot->PolicyRootOffset = (UINT32)((UINTN)PolicyRoot - (UINTN)MemPolicySnapshot); - MemPolicySnapshot->Size = MemPolicySnapshot->PolicyRootOffset + sizeof (SMM_SUPV_POLICY_ROOT_V1); - PolicyRoot->Type = SMM_SUPV_SECURE_POLICY_DESCRIPTOR_TYPE_MEM; - - // Then leave the heavy lifting job to the library - Status = PopulateMemoryPolicyEntries (MemPolicySnapshot, MEM_POLICY_SNAPSHOT_SIZE); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Fail to PopulateMemoryPolicyEntries %r\n", __FUNCTION__, Status)); - } - -Done: - return Status; -} - -/** - Allocate a static buffer for taking snapshot of memory policy when we lock down page table. - - @retval EFI_SUCCESS Buffer is allocated properly. - @retval EFI_OUT_OF_RESOURCES Cannot allocate enough resources for snapshot. -**/ -EFI_STATUS -AllocateMemForPolicySnapshot ( - VOID - ) -{ - MemPolicySnapshot = AllocatePages (EFI_SIZE_TO_PAGES (MEM_POLICY_SNAPSHOT_SIZE)); - if (MemPolicySnapshot == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - return EFI_SUCCESS; -} diff --git a/MmSupervisorPkg/Core/Policy/Policy.h b/MmSupervisorPkg/Core/Policy/Policy.h deleted file mode 100644 index 63016571..00000000 --- a/MmSupervisorPkg/Core/Policy/Policy.h +++ /dev/null @@ -1,117 +0,0 @@ -/** @file -Include file for MM Supervisor policy related implementation. - -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
-Copyright (c) 2020, AMD Incorporated. All rights reserved.
-Copyright (c) Microsoft Corporation. -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _MM_SUPV_POLICY_H_ -#define _MM_SUPV_POLICY_H_ - -#include - -extern SMM_SUPV_SECURE_POLICY_DATA_V1_0 *FirmwarePolicy; -extern SMM_SUPV_SECURE_POLICY_DATA_V1_0 *MemPolicySnapshot; - -/** - Dump a single memory policy data. -**/ -VOID -DumpMemPolicyEntry ( - SMM_SUPV_SECURE_POLICY_MEM_DESCRIPTOR_V1_0 *MemoryPolicy - ); - -/** - Helper function that populates memory policy on demands. - - @param[in] SmmPolicyBuffer Input buffer points to the entire v1.0 policy. - @param[in] Cr3 CR3 value to be converted, if input is zero, check the real HW register. - - @param[in] CpuIndex Logical number assigned to CPU. -**/ -EFI_STATUS -EFIAPI -PopulateMemoryPolicyEntries ( - IN SMM_SUPV_SECURE_POLICY_DATA_V1_0 *SmmPolicyBuffer, - IN UINT64 MaxPolicySize - ); - -/** - Compare memory policy in two SmmPolicy. - - @param SmmPolicyData1 The first data to compare. - @param SmmPolicyData2 The second data to compare. - - @retval FALSE If two memory policy not identical. - -**/ -BOOLEAN -CompareMemoryPolicy ( - SMM_SUPV_SECURE_POLICY_DATA_V1_0 *SmmPolicyData1, - SMM_SUPV_SECURE_POLICY_DATA_V1_0 *SmmPolicyData2 - ); - -/** - Prepare a snapshot of memory policy, this will be compared against the one generated when requested. - - @retval EFI_SUCCESS The security policy is successfully gathered. - @retval EFI_NOT_STARTED No memory policy snapshot buffer prepared. - @retval Errors Other error during populating memory errors. -**/ -EFI_STATUS -PrepareMemPolicySnapshot ( - VOID - ); - -/** - Allocate a static buffer for taking snapshot of memory policy when we lock down page table. - - @retval EFI_SUCCESS Buffer is allocated properly. - @retval EFI_OUT_OF_RESOURCES Cannot allocate enough resources for snapshot. -**/ -EFI_STATUS -AllocateMemForPolicySnapshot ( - VOID - ); - -/** - Policy validity check for a given security policy. Check covers policy range - overlap, policy entry header type mismatch, etc. - - @param[in] SmmSecurityPolicy - The address of applied SMM secure policy. - - @retval EFI_SECURITY_VIOLATION The supplied policy failed checking due to - overlapping, type mismatch, etc. - EFI_INVALID_PARAMETER The supplied policy pointer is a null pointer. - EFI_SUCCESS The supplied policy has passed supervisor - checking. -**/ -EFI_STATUS -SecurityPolicyCheck ( - IN SMM_SUPV_SECURE_POLICY_DATA_V1_0 *SmmSecurityPolicy - ); - -/** - Dump the smm policy data. -**/ -VOID -DumpSmmPolicyData ( - SMM_SUPV_SECURE_POLICY_DATA_V1_0 *Data - ); - -/** - Routine for initializing policy data provided by firmware. - - @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled. - @retval Errors The supervisor is unable to locate or protect the policy from firmware. - -**/ -EFI_STATUS -InitializePolicy ( - VOID - ); - -#endif // _MM_SUPV_POLICY_H_ diff --git a/MmSupervisorPkg/Core/Relocate/Relocate.h b/MmSupervisorPkg/Core/Relocate/Relocate.h index 010dadf1..db75c4ec 100644 --- a/MmSupervisorPkg/Core/Relocate/Relocate.h +++ b/MmSupervisorPkg/Core/Relocate/Relocate.h @@ -24,7 +24,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include #include #include #include diff --git a/MmSupervisorPkg/Core/Request/UpdateCommBuffer.c b/MmSupervisorPkg/Core/Request/UpdateCommBuffer.c index ce215bf0..552be529 100644 --- a/MmSupervisorPkg/Core/Request/UpdateCommBuffer.c +++ b/MmSupervisorPkg/Core/Request/UpdateCommBuffer.c @@ -48,25 +48,25 @@ VerifyandMoveUnblockedPages ( EFI_STATUS Status; if ((NewMemParam == NULL) || (OldMemParam == NULL)) { - DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are NULL - %p and %p!\n", __FUNCTION__, NewMemParam, OldMemParam)); + DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are NULL - %p and %p!\n", __func__, NewMemParam, OldMemParam)); Status = EFI_INVALID_PARAMETER; goto Done; } if (NewMemParam->MemoryDescriptor.NumberOfPages != OldMemParam->MemoryDescriptor.NumberOfPages) { - DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different sizes, this is not allowed!\n", __FUNCTION__)); + DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different sizes, this is not allowed!\n", __func__)); Status = EFI_SECURITY_VIOLATION; goto Done; } if (NewMemParam->MemoryDescriptor.Attribute != OldMemParam->MemoryDescriptor.Attribute) { - DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different attributes, this is not allowed!\n", __FUNCTION__)); + DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different attributes, this is not allowed!\n", __func__)); Status = EFI_SECURITY_VIOLATION; goto Done; } if (NewMemParam->MemoryDescriptor.Type != OldMemParam->MemoryDescriptor.Type) { - DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different types, this is not allowed!\n", __FUNCTION__)); + DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different types, this is not allowed!\n", __func__)); Status = EFI_SECURITY_VIOLATION; goto Done; } @@ -74,13 +74,13 @@ VerifyandMoveUnblockedPages ( // Okay, again, enough complaints, now get to work. Status = ProcessUnblockPages (NewMemParam); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to unblock the requested new communicate buffers - %r!\n", __FUNCTION__, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to unblock the requested new communicate buffers - %r!\n", __func__, Status)); goto Done; } Status = ProcessBlockPages (OldMemParam); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to block memory %r!\n", __FUNCTION__, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to block memory %r!\n", __func__, Status)); goto Done; } @@ -123,14 +123,14 @@ ProcessUpdateCommBufferRequest ( DEBUG (( DEBUG_ERROR, "%a - Comm buffer update requested after ready to lock, will not proceed!\n", - __FUNCTION__ + __func__ )); return EFI_ACCESS_DENIED; } // Some more sanity checks here if (UpdateCommBuffer == NULL) { - DEBUG ((DEBUG_ERROR, "%a - Invalid parameter detected - %p!\n", __FUNCTION__, UpdateCommBuffer)); + DEBUG ((DEBUG_ERROR, "%a - Invalid parameter detected - %p!\n", __func__, UpdateCommBuffer)); return EFI_INVALID_PARAMETER; } @@ -142,7 +142,7 @@ ProcessUpdateCommBufferRequest ( CopyMem (&(MmCoreDataDesc.MemoryDescriptor), &(mMmSupervisorAccessBuffer[Index]), sizeof (MmCoreDataDesc.MemoryDescriptor)); Status = VerifyandMoveUnblockedPages (&UpdateCommBuffer->NewCommBuffers[Index], &MmCoreDataDesc); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to moved unblocked buffer (%d) - %r!\n", __FUNCTION__, Index, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to moved unblocked buffer (%d) - %r!\n", __func__, Index, Status)); goto Done; } @@ -150,21 +150,22 @@ ProcessUpdateCommBufferRequest ( CopyMem (&mMmSupervisorAccessBuffer[Index], &(UpdateCommBuffer->NewCommBuffers[Index].MemoryDescriptor), sizeof (mMmSupervisorAccessBuffer[0])); } - // Next deal with the gMmCoreMailbox + // Next deal with the mMmCommMailboxBufferStatus // Craft a temp block for the existing buffer - MmCoreDataDesc.MemoryDescriptor.PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)gMmCoreMailbox; - MmCoreDataDesc.MemoryDescriptor.NumberOfPages = EFI_SIZE_TO_PAGES ((sizeof (MM_CORE_PRIVATE_DATA) + EFI_PAGE_MASK) & ~(EFI_PAGE_MASK)); + MmCoreDataDesc.MemoryDescriptor.PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)mMmCommMailboxBufferStatus; + MmCoreDataDesc.MemoryDescriptor.NumberOfPages = EFI_SIZE_TO_PAGES ((sizeof (MM_COMM_BUFFER_STATUS) + EFI_PAGE_MASK) & ~(EFI_PAGE_MASK)); MmCoreDataDesc.MemoryDescriptor.Attribute = EFI_MEMORY_XP | EFI_MEMORY_SP; Status = VerifyandMoveUnblockedPages (&UpdateCommBuffer->NewMmCoreData, &MmCoreDataDesc); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to moved unblocked buffer (%d) - %r!\n", __FUNCTION__, Index, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to moved unblocked buffer (%d) - %r!\n", __func__, Index, Status)); goto Done; } // Then update the cached global variable and prepare for the content fix up. - gMmCoreMailbox = (MM_CORE_PRIVATE_DATA *)(UINTN)UpdateCommBuffer->NewMmCoreData.MemoryDescriptor.PhysicalStart; + mMmCommMailboxBufferStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)UpdateCommBuffer->NewMmCoreData.MemoryDescriptor.PhysicalStart; + DEBUG ((DEBUG_ERROR, "%a - Updated mMmCommMailboxBufferStatus to new location - %p!\n", __func__, mMmCommMailboxBufferStatus)); - // Note: The content on the original communicate buffer and gMmCoreMailbox will be restored to the new buffer, + // Note: The content on the original communicate buffer and mMmCommMailboxBufferStatus will be restored to the new buffer, // so no need to worry about copy contents here. mAlreadyMoved = TRUE; From 2346f5d4963bff31c2e256762c9c7bc718ccb938 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Sun, 5 Oct 2025 00:33:28 -0700 Subject: [PATCH 05/36] handle MmSupervisorPkg/Library/MmSupervisorMemLib --- .../MmSupervisorCoreMemLib.inf | 1 - .../MmSupervisorMemLibSyscall.inf | 2 +- .../X86StandaloneMmMemLibInternal.c | 38 ++++++------------- 3 files changed, 12 insertions(+), 29 deletions(-) diff --git a/MmSupervisorPkg/Library/MmSupervisorMemLib/MmSupervisorCoreMemLib.inf b/MmSupervisorPkg/Library/MmSupervisorMemLib/MmSupervisorCoreMemLib.inf index a4b71361..f67131d6 100644 --- a/MmSupervisorPkg/Library/MmSupervisorMemLib/MmSupervisorCoreMemLib.inf +++ b/MmSupervisorPkg/Library/MmSupervisorMemLib/MmSupervisorCoreMemLib.inf @@ -51,5 +51,4 @@ MemoryAllocationLib [Guids] - gMmCoreDataHobGuid ## SOMETIMES_CONSUMES ## HOB gEfiMmPeiMmramMemoryReserveGuid ## SOMETIMES_CONSUMES ## HOB diff --git a/MmSupervisorPkg/Library/MmSupervisorMemLib/MmSupervisorMemLibSyscall.inf b/MmSupervisorPkg/Library/MmSupervisorMemLib/MmSupervisorMemLibSyscall.inf index bf9f4870..426db913 100644 --- a/MmSupervisorPkg/Library/MmSupervisorMemLib/MmSupervisorMemLibSyscall.inf +++ b/MmSupervisorPkg/Library/MmSupervisorMemLib/MmSupervisorMemLibSyscall.inf @@ -51,5 +51,5 @@ SysCallLib [Guids] - gMmCoreDataHobGuid ## SOMETIMES_CONSUMES ## HOB + gEfiSmmSmramMemoryGuid ## SOMETIMES_CONSUMES ## HOB gEfiMmPeiMmramMemoryReserveGuid ## SOMETIMES_CONSUMES ## HOB diff --git a/MmSupervisorPkg/Library/MmSupervisorMemLib/X86StandaloneMmMemLibInternal.c b/MmSupervisorPkg/Library/MmSupervisorMemLib/X86StandaloneMmMemLibInternal.c index 0b4b1174..24525ad9 100644 --- a/MmSupervisorPkg/Library/MmSupervisorMemLib/X86StandaloneMmMemLibInternal.c +++ b/MmSupervisorPkg/Library/MmSupervisorMemLib/X86StandaloneMmMemLibInternal.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include // @@ -87,9 +87,6 @@ MmMemLibInternalPopulateMmramRanges ( ) { VOID *HobStart; - EFI_HOB_GUID_TYPE *GuidHob; - MM_CORE_DATA_HOB_DATA *DataInHob; - MM_CORE_PRIVATE_DATA *MmCorePrivateData; EFI_HOB_GUID_TYPE *MmramRangesHob; EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData; EFI_MMRAM_DESCRIPTOR *MmramDescriptors; @@ -101,35 +98,22 @@ MmMemLibInternalPopulateMmramRanges ( // Extract MM Core Private context from the Hob. If absent search for // a Hob containing the MMRAM ranges // - GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart); - if (GuidHob == NULL) { - MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid); + MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid); + if (MmramRangesHob == NULL) { + MmramRangesHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid); if (MmramRangesHob == NULL) { return EFI_UNSUPPORTED; } + } - MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); - if ((MmramRangesHobData == NULL) || (MmramRangesHobData->Descriptor == NULL)) { - return EFI_UNSUPPORTED; - } - - mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions; - MmramDescriptors = MmramRangesHobData->Descriptor; - } else { - DataInHob = GET_GUID_HOB_DATA (GuidHob); - if (DataInHob == NULL) { - return EFI_UNSUPPORTED; - } - - MmCorePrivateData = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address; - if ((MmCorePrivateData == NULL) || (MmCorePrivateData->MmramRanges == 0)) { - return EFI_UNSUPPORTED; - } - - mMmMemLibInternalMmramCount = (UINTN)MmCorePrivateData->MmramRangeCount; - MmramDescriptors = (EFI_MMRAM_DESCRIPTOR *)(UINTN)MmCorePrivateData->MmramRanges; + MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob); + if ((MmramRangesHobData == NULL) || (MmramRangesHobData->Descriptor == NULL)) { + return EFI_UNSUPPORTED; } + mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions; + MmramDescriptors = MmramRangesHobData->Descriptor; + mMmMemLibInternalMmramRanges = AllocatePool (mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR)); if (mMmMemLibInternalMmramRanges) { CopyMem ( From e9bdf10a4e027e03de3d5221598d8d4fb18c654d Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Sun, 5 Oct 2025 00:33:53 -0700 Subject: [PATCH 06/36] remove the header and dec definitions --- MmSupervisorPkg/Include/Guid/MmCoreData.h | 126 ------------------ .../Include/Guid/MmCoreProfileData.h | 26 ---- MmSupervisorPkg/MmSupervisorPkg.dec | 3 - 3 files changed, 155 deletions(-) delete mode 100644 MmSupervisorPkg/Include/Guid/MmCoreData.h delete mode 100644 MmSupervisorPkg/Include/Guid/MmCoreProfileData.h diff --git a/MmSupervisorPkg/Include/Guid/MmCoreData.h b/MmSupervisorPkg/Include/Guid/MmCoreData.h deleted file mode 100644 index b8be92c6..00000000 --- a/MmSupervisorPkg/Include/Guid/MmCoreData.h +++ /dev/null @@ -1,126 +0,0 @@ -/** @file - MM Core data. - -Copyright (c) 2015, Intel Corporation. All rights reserved.
-Copyright (c) 2018 - 2021, Arm Limited. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __MM_CORE_DATA_H__ -#define __MM_CORE_DATA_H__ - -#define MM_CORE_DATA_HOB_GUID \ - { 0xa160bf99, 0x2aa4, 0x4d7d, { 0x99, 0x93, 0x89, 0x9c, 0xb1, 0x2d, 0xf3, 0x76 }} - -extern EFI_GUID gMmCoreDataHobGuid; - -typedef struct { - // - // Address pointer to MM_CORE_PRIVATE_DATA - // - EFI_PHYSICAL_ADDRESS Address; -} MM_CORE_DATA_HOB_DATA; - -/// -/// Define values for the communications buffer used when gEfiEventDxeDispatchGuid is -/// event signaled. This event is signaled by the DXE Core each time the DXE Core -/// dispatcher has completed its work. When this event is signaled, the MM Core -/// if notified, so the MM Core can dispatch MM drivers. If COMM_BUFFER_MM_DISPATCH_ERROR -/// is returned in the communication buffer, then an error occurred dispatching MM -/// Drivers. If COMM_BUFFER_MM_DISPATCH_SUCCESS is returned, then the MM Core -/// dispatched all the drivers it could. If COMM_BUFFER_MM_DISPATCH_RESTART is -/// returned, then the MM Core just dispatched the MM Driver that registered -/// the MM Entry Point enabling the use of MM Mode. In this case, the MM Core -/// should be notified again to dispatch more MM Drivers using MM Mode. -/// -#define COMM_BUFFER_MM_DISPATCH_ERROR 0x00 -#define COMM_BUFFER_MM_DISPATCH_SUCCESS 0x01 -#define COMM_BUFFER_MM_DISPATCH_RESTART 0x02 - -/// -/// Signature for the private structure shared between the MM IPL and the MM Core -/// -#define MM_CORE_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('m', 'm', 'i', 'c') - -/// -/// Private structure that is used to share information between the MM IPL and -/// the MM Core. This structure is allocated from memory of type EfiRuntimeServicesData. -/// Since runtime memory types are converted to available memory when a legacy boot -/// is performed, the MM Core must not access any fields of this structure if a legacy -/// boot is performed. As a result, the MM IPL must create an event notification -/// for the Legacy Boot event and notify the MM Core that a legacy boot is being -/// performed. The MM Core can then use this information to filter accesses to -/// thos structure. -/// -typedef struct { - UINT64 Signature; - - /// - /// The number of MMRAM ranges passed from the MM IPL to the MM Core. The MM - /// Core uses these ranges of MMRAM to initialize the MM Core memory manager. - /// - UINT64 MmramRangeCount; - - /// - /// A table of MMRAM ranges passed from the MM IPL to the MM Core. The MM - /// Core uses these ranges of MMRAM to initialize the MM Core memory manager. - /// - EFI_PHYSICAL_ADDRESS MmramRanges; - - /// - /// The MM Foundation Entry Point. The MM Core fills in this field when the - /// MM Core is initialized. The MM IPL is responsbile for registering this entry - /// point with the MM Configuration Protocol. The MM Configuration Protocol may - /// not be available at the time the MM IPL and MM Core are started, so the MM IPL - /// sets up a protocol notification on the MM Configuration Protocol and registers - /// the MM Foundation Entry Point as soon as the MM Configuration Protocol is - /// available. - /// - EFI_PHYSICAL_ADDRESS MmEntryPoint; - - /// - /// Boolean flag set to TRUE while an MMI is being processed by the MM Core. - /// - BOOLEAN MmEntryPointRegistered; - - /// - /// Boolean flag set to TRUE while an MMI is being processed by the MM Core. - /// - BOOLEAN InMm; - - /// - /// This field is set by the MM Core then the MM Core is initialized. This field is - /// used by the MM Base 2 Protocol and MM Communication Protocol implementations in - /// the MM IPL. - /// - EFI_PHYSICAL_ADDRESS Mmst; - - /// - /// This field is used by the MM Communication Protocol to pass a buffer into - /// a software MMI handler and for the software MMI handler to pass a buffer back to - /// the caller of the MM Communication Protocol. - /// - EFI_PHYSICAL_ADDRESS CommunicationBuffer; - - /// - /// This field is used by the MM Communication Protocol to pass the size of a buffer, - /// in bytes, into a software MMI handler and for the software MMI handler to pass the - /// size, in bytes, of a buffer back to the caller of the MM Communication Protocol. - /// - UINT64 BufferSize; - - /// - /// This field is used by the MM Communication Protocol to pass the return status from - /// a software MMI handler back to the caller of the MM Communication Protocol. - /// - UINT64 ReturnStatus; - - EFI_PHYSICAL_ADDRESS MmCoreImageBase; - UINT64 MmCoreImageSize; - EFI_PHYSICAL_ADDRESS MmCoreEntryPoint; - - EFI_PHYSICAL_ADDRESS StandaloneBfvAddress; -} MM_CORE_PRIVATE_DATA; - -#endif diff --git a/MmSupervisorPkg/Include/Guid/MmCoreProfileData.h b/MmSupervisorPkg/Include/Guid/MmCoreProfileData.h deleted file mode 100644 index 9f5f58f5..00000000 --- a/MmSupervisorPkg/Include/Guid/MmCoreProfileData.h +++ /dev/null @@ -1,26 +0,0 @@ -/** @file - MM Core data. - -Copyright (c) 2015, Intel Corporation. All rights reserved.
-Copyright (c) 2018, ARM Limited. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __MM_CORE_PROFILE_DATA_H__ -#define __MM_CORE_PROFILE_DATA_H__ - -#define MM_CORE_MM_PROFILE_DATA_GUID \ - { 0xf34014c5, 0xbcec, 0x4f36, { 0xad, 0xa7, 0x49, 0xff, 0xf5, 0xdd, 0x17, 0x9f }} - -extern EFI_GUID gMmCoreMmProfileGuid; - -typedef struct { - // - // Address pointer to MM_CORE_PRIVATE_DATA - // - EFI_PHYSICAL_ADDRESS Address; - UINT32 Size; -} MM_CORE_MM_PROFILE_DATA; - -#endif diff --git a/MmSupervisorPkg/MmSupervisorPkg.dec b/MmSupervisorPkg/MmSupervisorPkg.dec index b33714e5..502267fd 100644 --- a/MmSupervisorPkg/MmSupervisorPkg.dec +++ b/MmSupervisorPkg/MmSupervisorPkg.dec @@ -43,9 +43,6 @@ gMmSupervisorCoreGuid = { 0x4e4c89dc, 0xa452, 0x4b6b, { 0xb1, 0x83, 0xf1, 0x6a, 0x2a, 0x22, 0x37, 0x33 } } gMmSupervisorVerVendorGuid = { 0xd4adfc6f, 0x2f58, 0x4bcf, { 0xa8, 0x87, 0x05, 0xef, 0xb4, 0x7d, 0x42, 0x99 } } - ## Include/Guid/MmCoreData.h - gMmCoreDataHobGuid = { 0xa160bf99, 0x2aa4, 0x4d7d, { 0x99, 0x93, 0x89, 0x9c, 0xb1, 0x2d, 0xf3, 0x76 }} - [Guids.common.Private] gMmSupervisorRequestHandlerGuid = { 0x8c633b23, 0x1260, 0x4ea6, { 0x83, 0xf, 0x7d, 0xdc, 0x97, 0x38, 0x21, 0x11 } } gMmPagingAuditMmiHandlerGuid = { 0x59b149, 0x1117, 0x47dc, { 0x80, 0xbb, 0x11, 0x25, 0xe9, 0x8b, 0x41, 0x8c } } From bccf515bcd078d49fd48b3265c974e38fb812984 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Sun, 5 Oct 2025 00:34:27 -0700 Subject: [PATCH 07/36] Decouple usage from SEA --- SeaPkg/Core/Test/ResponderValidationTestLib.c | 2 -- SeaPkg/Library/SmmCpuFeaturesLib/SmmStm.c | 1 - 2 files changed, 3 deletions(-) diff --git a/SeaPkg/Core/Test/ResponderValidationTestLib.c b/SeaPkg/Core/Test/ResponderValidationTestLib.c index 239d144e..0b33fdbb 100644 --- a/SeaPkg/Core/Test/ResponderValidationTestLib.c +++ b/SeaPkg/Core/Test/ResponderValidationTestLib.c @@ -12,7 +12,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include #include #include @@ -25,7 +24,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -extern MM_CORE_PRIVATE_DATA *gMmCorePrivate; extern SMM_SUPV_SECURE_POLICY_DATA_V1_0 *MemPolicySnapshot; extern SMM_SUPV_SECURE_POLICY_DATA_V1_0 *FirmwarePolicy; diff --git a/SeaPkg/Library/SmmCpuFeaturesLib/SmmStm.c b/SeaPkg/Library/SmmCpuFeaturesLib/SmmStm.c index a2d5def5..6d4e7899 100644 --- a/SeaPkg/Library/SmmCpuFeaturesLib/SmmStm.c +++ b/SeaPkg/Library/SmmCpuFeaturesLib/SmmStm.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include From 3269fcb9c41213b536e9f13e1354c9495b05a08b Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Sun, 5 Oct 2025 23:27:36 -0700 Subject: [PATCH 08/36] Now it is a dxe driver --- MmSupervisorPkg/Core/MmSupervisorCore.c | 22 +- .../MmPeiLaunchers/Common/MmIplCommon.c | 3 +- .../Drivers/MmPeiLaunchers/MmDxeSupport.c | 428 +----------------- .../Drivers/MmPeiLaunchers/MmDxeSupport.inf | 15 +- .../Guid/MmSupervisorRequestData.h | 0 5 files changed, 24 insertions(+), 444 deletions(-) rename MmSupervisorPkg/{Private => Include}/Guid/MmSupervisorRequestData.h (100%) diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.c b/MmSupervisorPkg/Core/MmSupervisorCore.c index 68a3da91..9494bd10 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.c +++ b/MmSupervisorPkg/Core/MmSupervisorCore.c @@ -485,19 +485,14 @@ MmEntryPoint ( CopyMem (&mMmCommunicationBufferStatus, (MM_COMM_BUFFER_STATUS*)(UINTN)mMmCommMailboxBufferStatus, sizeof (MM_COMM_BUFFER_STATUS)); if (mMmCommunicationBufferStatus.IsCommBufferValid) { - if (mMmCommunicationBufferStatus.CommunicateChannel == MM_SUPERVISOR_BUFFER_T) { - CommunicationBuffer = mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].PhysicalStart; - } else { - CommunicationBuffer = mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].PhysicalStart; - } - // // Synchronous MMI for MM Core or request from Communicate protocol // - if (CommunicationBuffer == mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].PhysicalStart) { + if (!mMmCommunicationBufferStatus.TalkToSupervisor) { // // This should be user communicate channel, follow normal user channel iterations, but use ring 3 buffer to hold BufferSize changes // + CommunicationBuffer = mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].PhysicalStart; ZeroMem (mInternalCommBufferCopy[MM_USER_BUFFER_T], EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages)); CopyMem (mInternalCommBufferCopy[MM_USER_BUFFER_T], (VOID *)(UINTN)CommunicationBuffer, EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages)); CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mInternalCommBufferCopy[MM_USER_BUFFER_T]; @@ -539,10 +534,11 @@ MmEntryPoint ( mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; mMmCommunicationBufferStatus.ReturnBufferSize = BufferSize; mMmCommunicationBufferStatus.ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; - } else if (CommunicationBuffer == mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].PhysicalStart) { + } else { // // This should be supervisor communicate channel, everything can be ring 0 buffer fine // + CommunicationBuffer = mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].PhysicalStart; ZeroMem (mInternalCommBufferCopy[MM_SUPERVISOR_BUFFER_T], EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].NumberOfPages)); CopyMem (mInternalCommBufferCopy[MM_SUPERVISOR_BUFFER_T], (VOID *)(UINTN)CommunicationBuffer, EFI_PAGES_TO_SIZE (mMmSupervisorAccessBuffer[MM_SUPERVISOR_BUFFER_T].NumberOfPages)); CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mInternalCommBufferCopy[MM_SUPERVISOR_BUFFER_T]; @@ -556,6 +552,7 @@ MmEntryPoint ( DEBUG ((DEBUG_ERROR, "%a Input buffer size is larger than maximal allowed size, something is off...\n", __func__)); ASSERT (FALSE); mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; + mMmCommunicationBufferStatus.TalkToSupervisor = FALSE; mMmCommunicationBufferStatus.ReturnBufferSize = 0; mMmCommunicationBufferStatus.ReturnStatus = EFI_BAD_BUFFER_SIZE; goto Cleanup; @@ -580,19 +577,14 @@ MmEntryPoint ( ASSERT (FALSE); } - mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; + mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; + mMmCommunicationBufferStatus.TalkToSupervisor = FALSE; mMmCommunicationBufferStatus.ReturnBufferSize = BufferSize; mMmCommunicationBufferStatus.ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; // // Do not handle asynchronous MMI sources. This cannot be it... // goto Cleanup; - } else { - // - // If CommunicationBuffer is not in valid address scope, return EFI_ACCESS_DENIED - // - mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; - mMmCommunicationBufferStatus.ReturnStatus = EFI_ACCESS_DENIED; } } } else { diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c index 57a1323b..300a4cbf 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c @@ -121,7 +121,6 @@ SmmCommunicationCommunicateWorker ( return EFI_BAD_BUFFER_SIZE; } DEBUG ((DEBUG_INFO, "SmmCommunicationCommunicateWorker: Using Supervisor Communicate Buffer - %p, %p, %x\n", CommunicateHeader, CommunicateBufferPhysical, TempCommSize)); - mMmCommBufferStatus->CommunicateChannel = MM_SUPERVISOR_BUFFER_T; } else { CommunicateHeader = mMmUserCommonBuffer; CommunicateBufferPhysical = mMmUserCommonBufferPhysical; @@ -134,9 +133,9 @@ SmmCommunicationCommunicateWorker ( return EFI_BAD_BUFFER_SIZE; } - mMmCommBufferStatus->CommunicateChannel = MM_USER_BUFFER_T; DEBUG ((DEBUG_INFO, "SmmCommunicationCommunicateWorker: Using User Communicate Buffer - %p, %p, %x\n", CommunicateHeader, CommunicateBufferPhysical, TempCommSize)); } + mMmCommBufferStatus->TalkToSupervisor = TalkToSupervisor; if (CommunicateHeader != CommBuffer) { CopyMem (CommunicateHeader, CommBuffer, TempCommSize); diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c index 8f7e0557..416fe2b4 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c @@ -19,7 +19,6 @@ #include #include #include -#include #include // MU_CHANGE: MM_SUPV: Added MM Supervisor request data structure #include @@ -38,73 +37,6 @@ // Function prototypes from produced protocols // -/** - Communicates with a registered handler. - - This function provides a service to send and receive messages from a registered - UEFI service. This function is part of the SMM Communication Protocol that may - be called in physical mode prior to SetVirtualAddressMap() and in virtual mode - after SetVirtualAddressMap(). - - @param[in] This The EFI_SMM_COMMUNICATION_PROTOCOL instance. - @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM. - @param[in, out] CommSize The size of the data buffer being passed in. On exit, 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 The CommBuffer 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 -SmmCommunicationCommunicate ( - IN CONST EFI_SMM_COMMUNICATION_PROTOCOL *This, - IN OUT VOID *CommBuffer, - IN OUT UINTN *CommSize OPTIONAL - ); - -/** - 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_COMMUNICATION_PROTOCOL instance. - @param[in] CommBufferPhysical Physical address of the MM communication buffer - @param[in] CommBufferVirtual Virtual address of the MM communication buffer - @param[in] CommSize The size of the data buffer being passed in. On exit, 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 The CommBuffer 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 -SmmCommunicationMmCommunicate2 ( - IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This, - IN OUT VOID *CommBufferPhysical, - IN OUT VOID *CommBufferVirtual, - IN OUT UINTN *CommSize OPTIONAL - ); - // MU_CHANGE: MM_SUPV: Supervisor communication function prototype /** @@ -156,20 +88,6 @@ SmmIplReadyToLockEventNotify ( IN VOID *Context ); -/** - Event notification that is fired when a GUIDed Event Group is signaled. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplGuidedEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ); - /** Event notification that is fired when EndOfDxe Event Group is signaled. @@ -184,23 +102,6 @@ SmmIplEndOfDxeEventNotify ( IN VOID *Context ); -/** - Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE. - - This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. - It convers pointer to new virtual address. - - @param Event Event whose notification function is being invoked. - @param Context Pointer to the notification function's context. - -**/ -VOID -EFIAPI -SmmIplSetVirtualAddressNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ); - // // Data structure used to declare a table of protocol notifications and event // notifications required by the SMM IPL @@ -220,20 +121,6 @@ typedef struct { // EFI_HANDLE mSmmIplHandle = NULL; -// -// SMM Communication Protocol instance -// -EFI_SMM_COMMUNICATION_PROTOCOL mSmmCommunication = { - SmmCommunicationCommunicate -}; - -// -// PI 1.7 MM Communication Protocol 2 instance -// -EFI_MM_COMMUNICATION2_PROTOCOL mMmCommunication2 = { - SmmCommunicationMmCommunicate2 -}; - // MU_CHANGE: MM_SUPV: Supervisor communication protocol instance // // PI 1.7 MM Communication Protocol 2 instance @@ -248,7 +135,6 @@ MM_SUPERVISOR_COMMUNICATION_PROTOCOL mMmSupvCommunication = { // SMM IPL global variables // EFI_SMM_CONTROL2_PROTOCOL *mSmmControl2; -EFI_SMRAM_DESCRIPTOR *mCurrentSmramRange; BOOLEAN mSmmLocked = FALSE; BOOLEAN mEndOfDxe = FALSE; @@ -265,13 +151,7 @@ SMM_IPL_EVENT_NOTIFICATION mSmmIplEvents[] = { // the associated event is immediately signalled, so the notification function will be executed and the // DXE SMM Ready To Lock Protocol will be found if it is already in the handle database. // - { TRUE, TRUE, &gEfiDxeSmmReadyToLockProtocolGuid, SmmIplReadyToLockEventNotify, &gEfiDxeSmmReadyToLockProtocolGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on EndOfDxe event. When this notification is established, - // the associated event is immediately signalled, so the notification function will be executed and the - // SMM End Of Dxe Protocol will be found if it is already in the handle database. - // - { FALSE, TRUE, &gEfiEndOfDxeEventGroupGuid, SmmIplGuidedEventNotify, &gEfiEndOfDxeEventGroupGuid, TPL_CALLBACK, NULL }, + { TRUE, TRUE, &gEfiDxeSmmReadyToLockProtocolGuid, SmmIplReadyToLockEventNotify, &gEfiDxeSmmReadyToLockProtocolGuid, TPL_CALLBACK - 1, NULL }, // // Declare event notification on EndOfDxe event. This is used to set EndOfDxe event signaled flag. // @@ -282,21 +162,6 @@ SMM_IPL_EVENT_NOTIFICATION mSmmIplEvents[] = { // { FALSE, TRUE, &gEfiEventReadyToBootGuid, SmmIplReadyToLockEventNotify, &gEfiEventReadyToBootGuid, TPL_CALLBACK, NULL }, // - // Declare event notification on Exit Boot Services Event Group. This is used to inform the SMM Core - // to notify SMM driver that system enter exit boot services. - // - { FALSE, FALSE, &gEfiEventExitBootServicesGuid, SmmIplGuidedEventNotify, &gEfiEventExitBootServicesGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on Ready To Boot Event Group. This is used to inform the SMM Core - // to notify SMM driver that system enter ready to boot. - // - { FALSE, FALSE, &gEfiEventReadyToBootGuid, SmmIplGuidedEventNotify, &gEfiEventReadyToBootGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on SetVirtualAddressMap() Event Group. This is used to convert mMmCommBufferStatus - // and mSmmControl2 from physical addresses to virtual addresses. - // - { FALSE, FALSE, &gEfiEventVirtualAddressChangeGuid, SmmIplSetVirtualAddressNotify, NULL, TPL_CALLBACK, NULL }, - // // Terminate the table of event notifications // { FALSE, FALSE, NULL, NULL, NULL, TPL_CALLBACK, NULL } @@ -372,102 +237,6 @@ SupvCommunicationCommunicate ( // MU_CHANGE: Abstracted MM communicate routine to common file for both PEI and DXE file -/** - Communicates with a registered handler. - - This function provides a service to send and receive messages from a registered - UEFI service. This function is part of the SMM Communication Protocol that may - be called in physical mode prior to SetVirtualAddressMap() and in virtual mode - after SetVirtualAddressMap(). - - @param[in] This The EFI_SMM_COMMUNICATION_PROTOCOL instance. - @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM. - @param[in, out] CommSize The size of the data buffer being passed in. On exit, 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 The CommBuffer 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 -SmmCommunicationCommunicate ( - IN CONST EFI_SMM_COMMUNICATION_PROTOCOL *This, - IN OUT VOID *CommBuffer, - IN OUT UINTN *CommSize OPTIONAL - ) -{ - // MU_CHANGE: MM_SUPV: Abstracted implementation to SmmCommunicationCommunicateWorker for - // DXE and PEI, Supervisor and User. - return SmmCommunicationCommunicateWorker (FALSE, CommBuffer, CommSize); -} - -/** - 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_COMMUNICATION_PROTOCOL instance. - @param[in] CommBufferPhysical Physical address of the MM communication buffer - @param[in] CommBufferVirtual Virtual address of the MM communication buffer - @param[in] CommSize The size of the data buffer being passed in. On exit, 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 The CommBuffer 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 -SmmCommunicationMmCommunicate2 ( - IN CONST EFI_MM_COMMUNICATION2_PROTOCOL *This, - IN OUT VOID *CommBufferPhysical, - IN OUT VOID *CommBufferVirtual, - IN OUT UINTN *CommSize OPTIONAL - ) -{ - return SmmCommunicationCommunicate ( - &mSmmCommunication, - CommBufferVirtual, - CommSize - ); -} - -/** - Event notification that is fired when GUIDed Event Group is signaled. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplGuidedEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - SmmIplGuidedEventNotifyWorker ((EFI_GUID *)Context); -} - /** Event notification that is fired when EndOfDxe Event Group is signaled. @@ -549,11 +318,6 @@ SmmIplReadyToLockEventNotify ( } } - // - // Inform SMM User drivers that the DxeSmmReadyToLock protocol was installed - // - SmmIplGuidedEventNotify (Event, (VOID *)&gEfiDxeSmmReadyToLockProtocolGuid); - // MU_CHANGE: MM_SUPV: Specifically send ready to lock to supervisor after users // // Finally, we inform SMM Core that the DxeSmmReadyToLock protocol was installed @@ -579,31 +343,6 @@ SmmIplReadyToLockEventNotify ( mSmmLocked = TRUE; } -/** - Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE. - - This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. - It convers pointer to new virtual address. - - @param Event Event whose notification function is being invoked. - @param Context Pointer to the notification function's context. - -**/ -VOID -EFIAPI -SmmIplSetVirtualAddressNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EfiConvertPointer (0x0, (VOID **)&mSmmControl2); - // MU_CHANGE: These "external "entries need update since used in MM Communication routine - EfiConvertPointer (0x0, (VOID **)&mMmSupvCommonBuffer); - EfiConvertPointer (0x0, (VOID **)&mMmUserCommonBuffer); - EfiConvertPointer (0x0, (VOID **)&mMmCommBufferStatus); - EfiConvertPointer (0x0, (VOID **)&mMmSupvCommunication.CommunicationRegion.VirtualStart); -} - // MM_SUPV: Update communicate buffer when entering DXE. /** @@ -734,150 +473,25 @@ UpdateDxeCommunicateBuffer ( mMmUserCommonBufferPhysical = NewUserCommBuffer; mMmSupvCommonBufferPhysical = NewSupvCommBuffer; - // Update supervisor communicate protocol communicate regions - mMmSupvCommunication.CommunicationRegion.PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)NewSupvCommBuffer; - mMmSupvCommunication.CommunicationRegion.VirtualStart = (EFI_PHYSICAL_ADDRESS)(UINTN)NewSupvCommBuffer; + // TODO: This is not right: + EFI_PEI_HOB_POINTERS GuidHob; + MM_COMM_BUFFER *CommBuffer; -Done: - return Status; -} - -/** - Publish EFI MM communication region tables for both user and supervisor with updated buffer - addresses. - - @param[in] UpdatedCommBuffer Pointer to hold the updated comm buffer information structure. - - @retval EFI_SUCCESS - @return Others Some error occurs. -**/ -EFI_STATUS -EFIAPI -PublishMmCommunicationBuffer ( - IN MM_SUPERVISOR_COMM_UPDATE_BUFFER *UpdatedCommBuffer - ) -{ - EFI_STATUS Status = EFI_NOT_FOUND; - UINT32 DescriptorSize; - EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable; - EFI_MEMORY_DESCRIPTOR *Entry; - // MU_CHANGE Starts: MM_SUPV: Fetch allocated communication buffer from HOBs. - EFI_GUID *ConfTableGuid; - EFI_PEI_HOB_POINTERS GuidHob; - MM_COMM_REGION_HOB *CommRegionHob; - MM_SUPERVISOR_COMM_UPDATE_BUFFER TempCommBuffer; - UINTN Index; - - PiSmmCommunicationRegionTable = NULL; - - if (UpdatedCommBuffer != NULL) { - CopyMem (&TempCommBuffer, UpdatedCommBuffer, sizeof (*UpdatedCommBuffer)); - } else { - ZeroMem (&TempCommBuffer, sizeof (TempCommBuffer)); - GuidHob.Guid = GetFirstGuidHob (&gMmCommonRegionHobGuid); - // Get the information from the HOBs as before - while (GuidHob.Guid != NULL) { - CommRegionHob = GET_GUID_HOB_DATA (GuidHob.Guid); - if ((CommRegionHob->MmCommonRegionType >= MM_OPEN_BUFFER_CNT)) { - // Unrecognized buffer type, do not proceed with comm buffer table installation - DEBUG ((DEBUG_ERROR, "%a Unsupported communication region type discovered (0x%x), the communication buffer could be misconfigured!!!\n", __FUNCTION__, CommRegionHob->MmCommonRegionType)); - Status = EFI_UNSUPPORTED; - ASSERT (FALSE); - goto Done; - } - - TempCommBuffer.NewCommBuffers[CommRegionHob->MmCommonRegionType].MemoryDescriptor.NumberOfPages = CommRegionHob->MmCommonRegionPages; - TempCommBuffer.NewCommBuffers[CommRegionHob->MmCommonRegionType].MemoryDescriptor.PhysicalStart = CommRegionHob->MmCommonRegionAddr; - - // MU_CHANGE Starts: MM_SUPV: Fetch allocated communication buffer from HOBs - // And publish notification when the table is installed. - GuidHob.Guid = GET_NEXT_HOB (GuidHob); - GuidHob.Guid = GetNextGuidHob (&gMmCommonRegionHobGuid, GuidHob.Guid); - } + GuidHob.Guid = GetFirstGuidHob (&gMmCommBufferHobGuid); + if (GuidHob.Guid == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to find MM Communication Buffer HOB\n")); + DEBUG ((DEBUG_ERROR, "Only Root MMI Handlers will be supported!\n")); + return Status; } + CommBuffer = (MM_COMM_BUFFER *)GET_GUID_HOB_DATA (GuidHob.Guid); + CommBuffer->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)mMmUserCommonBuffer; + CommBuffer->Status = (EFI_PHYSICAL_ADDRESS)(UINTN)NewMmCommBufferStatus; - for (Index = 0; Index < MM_OPEN_BUFFER_CNT; Index++) { - PiSmmCommunicationRegionTable = NULL; - if (Index == MM_USER_BUFFER_T) { - ConfTableGuid = &gEdkiiPiSmmCommunicationRegionTableGuid; - } else if (Index == MM_SUPERVISOR_BUFFER_T) { - ConfTableGuid = &gMmSupervisorCommunicationRegionTableGuid; - } - - DescriptorSize = sizeof (EFI_MEMORY_DESCRIPTOR); - // - // Make sure Size != sizeof(EFI_MEMORY_DESCRIPTOR). This will - // prevent people from having pointer math bugs in their code. - // now you have to use *DescriptorSize to make things work. - // - DescriptorSize += sizeof (UINT64) - (DescriptorSize % sizeof (UINT64)); - - // - // Allocate and fill PiSmmCommunicationRegionTable - // - PiSmmCommunicationRegionTable = AllocateReservedPool (sizeof (EDKII_PI_SMM_COMMUNICATION_REGION_TABLE) + DescriptorSize); - ASSERT (PiSmmCommunicationRegionTable != NULL); - // MU_CHANGE: MM_SUPV: Exit loop if allocation failed. - if (PiSmmCommunicationRegionTable == NULL) { - DEBUG ((DEBUG_ERROR, "%a Failed to allocate buffer for communication buffer table!!!\n", __FUNCTION__)); - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - ZeroMem (PiSmmCommunicationRegionTable, sizeof (EDKII_PI_SMM_COMMUNICATION_REGION_TABLE) + DescriptorSize); - - PiSmmCommunicationRegionTable->Version = EDKII_PI_SMM_COMMUNICATION_REGION_TABLE_VERSION; - PiSmmCommunicationRegionTable->NumberOfEntries = 1; - PiSmmCommunicationRegionTable->DescriptorSize = DescriptorSize; - Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1); - Entry->Type = EfiConventionalMemory; - Entry->PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)TempCommBuffer.NewCommBuffers[Index].MemoryDescriptor.PhysicalStart; // MU_CHANGE: MM_SUPV: BAR from HOB - ASSERT (Entry->PhysicalStart != 0); - // MU_CHANGE: MM_SUPV: Exit loop if PhysicalStart is null pointer. - if (Entry->PhysicalStart == 0) { - DEBUG (( - DEBUG_ERROR, - "%a Target HOB does not contain valid communication buffer data: type: 0x%x, addr: 0x%p, pages: 0x%x!!!\n", - __FUNCTION__, - Index, - TempCommBuffer.NewCommBuffers[Index].MemoryDescriptor.PhysicalStart, - TempCommBuffer.NewCommBuffers[Index].MemoryDescriptor.NumberOfPages - )); - Status = EFI_NOT_STARTED; - goto Done; - } - - Entry->VirtualStart = 0; - Entry->NumberOfPages = TempCommBuffer.NewCommBuffers[Index].MemoryDescriptor.NumberOfPages; // MU_CHANGE: MM_SUPV: Buffer size from HOB - Entry->Attribute = 0; - - DEBUG ((DEBUG_INFO, "PiSmmCommunicationRegionTable:(0x%x)\n", PiSmmCommunicationRegionTable)); - DEBUG ((DEBUG_INFO, " Version - 0x%x\n", PiSmmCommunicationRegionTable->Version)); - DEBUG ((DEBUG_INFO, " NumberOfEntries - 0x%x\n", PiSmmCommunicationRegionTable->NumberOfEntries)); - DEBUG ((DEBUG_INFO, " DescriptorSize - 0x%x\n", PiSmmCommunicationRegionTable->DescriptorSize)); - DEBUG ((DEBUG_INFO, "Entry:(0x%x)\n", Entry)); - DEBUG ((DEBUG_INFO, " Type - 0x%x\n", Entry->Type)); - DEBUG ((DEBUG_INFO, " PhysicalStart - 0x%lx\n", Entry->PhysicalStart)); - DEBUG ((DEBUG_INFO, " VirtualStart - 0x%lx\n", Entry->VirtualStart)); - DEBUG ((DEBUG_INFO, " NumberOfPages - 0x%lx\n", Entry->NumberOfPages)); - DEBUG ((DEBUG_INFO, " Attribute - 0x%lx\n", Entry->Attribute)); - - // - // Publish this table, so that other driver can use the buffer. - // - Status = gBS->InstallConfigurationTable (ConfTableGuid, PiSmmCommunicationRegionTable); - if (EFI_ERROR (Status)) { - goto Done; - } - } + // Update supervisor communicate protocol communicate regions + mMmSupvCommunication.CommunicationRegion.PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)NewSupvCommBuffer; + mMmSupvCommunication.CommunicationRegion.VirtualStart = (EFI_PHYSICAL_ADDRESS)(UINTN)NewSupvCommBuffer; Done: - if (EFI_ERROR (Status) && (PiSmmCommunicationRegionTable != NULL)) { - // We failed.. At least clean up the mass. - FreePool (PiSmmCommunicationRegionTable); - } - - // MU_CHANGE Ends: MM_SUPV. return Status; } @@ -942,14 +556,6 @@ MmDxeSupportEntry ( return Status; } - // Needs clean up - Status = PublishMmCommunicationBuffer (&NewCommBuffer); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Failed to publish communicate buffer configuration tables - %r\n", __FUNCTION__, Status)); - ASSERT_EFI_ERROR (Status); - return Status; - } - // Query it another time to make sure the change took effect Status = QuerySupervisorVersion (&VersionInfo); if (EFI_ERROR (Status)) { @@ -963,10 +569,6 @@ MmDxeSupportEntry ( // Status = gBS->InstallMultipleProtocolInterfaces ( &mSmmIplHandle, - &gEfiSmmCommunicationProtocolGuid, - &mSmmCommunication, - &gEfiMmCommunication2ProtocolGuid, - &mMmCommunication2, &gMmSupervisorCommunicationProtocolGuid, &mMmSupvCommunication, // MU_CHANGE: MM_SUPV NULL diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf index a3fd91d0..03063e92 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf @@ -12,14 +12,11 @@ INF_VERSION = 0x00010005 BASE_NAME = MmDxeSupport FILE_GUID = F0825F4F-D6A2-4F61-A6C0-5F01A86C80FF - MODULE_TYPE = DXE_RUNTIME_DRIVER + MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 PI_SPECIFICATION_VERSION = 0x0001000A ENTRY_POINT = MmDxeSupportEntry -# dev/202502, release/202502 -#Track : 00000002 | MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf | 3dd4263d24d9aab1423696633b261277 | 2025-08-29T23-27-13 | ce057040b889378a53850c22545f0ae134f4ea4e - # # The following information is for reference only and not required by the build tools. # @@ -46,14 +43,10 @@ DebugLib UefiBootServicesTableLib UefiLib - UefiRuntimeLib ReportStatusCodeLib SafeIntLib #MU_CHANGE: BZ3398 [Protocols] - gEfiSmmBase2ProtocolGuid ## PRODUCES - gEfiSmmCommunicationProtocolGuid ## PRODUCES - gEfiMmCommunication2ProtocolGuid ## PRODUCES gEfiSmmControl2ProtocolGuid ## CONSUMES ## NOTIFY ## SOMETIMES_CONSUMES @@ -62,18 +55,12 @@ gMmSupervisorCommunicationProtocolGuid ## PRODUCES [Guids] - ## SOMETIMES_CONSUMES ## Event - ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communication - gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## Event ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communication gEfiEventReadyToBootGuid - gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event gMmCommonRegionHobGuid ## CONSUMES gMmSupervisorRequestHandlerGuid ## CONSUMES - gMmSupervisorCommunicationRegionTableGuid ## CONSUMES - gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES gMmCommBufferHobGuid ## CONSUMES [Depex] diff --git a/MmSupervisorPkg/Private/Guid/MmSupervisorRequestData.h b/MmSupervisorPkg/Include/Guid/MmSupervisorRequestData.h similarity index 100% rename from MmSupervisorPkg/Private/Guid/MmSupervisorRequestData.h rename to MmSupervisorPkg/Include/Guid/MmSupervisorRequestData.h From 6a27232e80cbac3078bcf08d1c156ea41dec8fd8 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 6 Oct 2025 10:24:32 -0700 Subject: [PATCH 09/36] changes to allow mm communicate to update the comm buffer --- .../Drivers/MmPeiLaunchers/MmDxeSupport.c | 32 +++++++++++++++++++ .../Drivers/MmPeiLaunchers/MmDxeSupport.inf | 1 + 2 files changed, 33 insertions(+) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c index 416fe2b4..e9fd3115 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -522,6 +523,7 @@ MmDxeSupportEntry ( // MU_CHANGE: MM_SUPV: Test supervisor communication before publishing protocol MM_SUPERVISOR_VERSION_INFO_BUFFER VersionInfo; MM_SUPERVISOR_COMM_UPDATE_BUFFER NewCommBuffer; + MM_COMM_BUFFER_UPDATE_PROTOCOL *MmCommBufferUpdate; // MU_CHANGE: MM_SUPV: Initialize Comm buffer from HOBs first Status = InitializeCommunicationBufferFromHob ( @@ -541,6 +543,14 @@ MmDxeSupportEntry ( return Status; } + Status = gBS->LocateProtocol (&gMmCommBufferUpdateProtocolGuid, NULL, NULL); + if (!EFI_ERROR (Status)) { + // MM_COMM_BUFFER_UPDATE_PROTOCOL is already installed, this can't be right + DEBUG ((DEBUG_ERROR, "%a MM_COMM_BUFFER_UPDATE_PROTOCOL already installed, skip update\n", __FUNCTION__)); + ASSERT (FALSE); + return EFI_ALREADY_STARTED; + } + // MU_CHANGE: MM_SUPV: We are just making sure this communication to supervisor does not fail. Status = QuerySupervisorVersion (&VersionInfo); if (EFI_ERROR (Status)) { @@ -563,6 +573,28 @@ MmDxeSupportEntry ( return Status; } + MmCommBufferUpdate = AllocateZeroPool (sizeof (*MmCommBufferUpdate)); + if (MmCommBufferUpdate == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + MmCommBufferUpdate->Version = MM_COMMUNICATE_BUFFER_UPDATE_PROTOCOL_VERSION; + MmCommBufferUpdate->UpdatedCommBuffer.PhysicalStart = NewCommBuffer.NewCommBuffers[MM_USER_BUFFER_T].MemoryDescriptor.PhysicalStart; + MmCommBufferUpdate->UpdatedCommBuffer.NumberOfPages = NewCommBuffer.NewCommBuffers[MM_USER_BUFFER_T].MemoryDescriptor.NumberOfPages; + MmCommBufferUpdate->UpdatedCommBuffer.Status = NewCommBuffer.NewMmCoreData.MemoryDescriptor.PhysicalStart; + + Status = gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gMmCommBufferUpdateProtocolGuid, + MmCommBufferUpdate, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a Failed to install MM_COMM_BUFFER_UPDATE_PROTOCOL - %r\n", __FUNCTION__, Status)); + FreePool (MmCommBufferUpdate); + return Status; + } + // MU_CHANGE: Since we already set up everything, directly move to protocol installation. // // Install SMM Base2 Protocol and SMM Communication Protocol diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf index 03063e92..4bee5d0f 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmDxeSupport.inf @@ -53,6 +53,7 @@ ## UNDEFINED # Used to do smm communication gEfiDxeSmmReadyToLockProtocolGuid gMmSupervisorCommunicationProtocolGuid ## PRODUCES + gMmCommBufferUpdateProtocolGuid ## PRODUCES [Guids] ## SOMETIMES_CONSUMES ## Event From 2e104a6579700621f52905a311dcbe8eaadae5b0 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Tue, 7 Oct 2025 16:57:30 -0700 Subject: [PATCH 10/36] this should do better --- MmSupervisorPkg/Core/Dispatcher/Dispatcher.c | 27 +- .../Drivers/MmPeiLaunchers/MmIplPei.c | 328 +----------- .../Drivers/MmPeiLaunchers/MmPeiSupport.c | 490 ++++++++++++++++++ .../Drivers/MmPeiLaunchers/MmPeiSupport.inf | 88 ++++ 4 files changed, 594 insertions(+), 339 deletions(-) create mode 100644 MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c create mode 100644 MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf diff --git a/MmSupervisorPkg/Core/Dispatcher/Dispatcher.c b/MmSupervisorPkg/Core/Dispatcher/Dispatcher.c index 248f577d..d639dde3 100644 --- a/MmSupervisorPkg/Core/Dispatcher/Dispatcher.c +++ b/MmSupervisorPkg/Core/Dispatcher/Dispatcher.c @@ -797,9 +797,7 @@ MmAddToDriverList ( return EFI_SUCCESS; } -#define COMM_BUFFER_MM_DISPATCH_ERROR 0x00 -#define COMM_BUFFER_MM_DISPATCH_SUCCESS 0x01 -#define COMM_BUFFER_MM_DISPATCH_RESTART 0x02 + /** This function is the main entry point for an SMM handler dispatch or communicate-based callback. @@ -858,24 +856,11 @@ MmDriverDispatchHandler ( // Check to see if CommBuffer and CommBufferSize are valid // if ((CommBuffer != NULL) && (CommBufferSize != NULL)) { - if (*CommBufferSize > 0) { - if (Status == EFI_NOT_READY) { - // - // If a the SMM Core Entry Point was just registered, then set flag to - // request the SMM Dispatcher to be restarted. - // - *(UINT8 *)CommBuffer = COMM_BUFFER_MM_DISPATCH_RESTART; - } else if (!EFI_ERROR (Status)) { - // - // Set the flag to show that the SMM Dispatcher executed without errors - // - *(UINT8 *)CommBuffer = COMM_BUFFER_MM_DISPATCH_SUCCESS; - } else { - // - // Set the flag to show that the SMM Dispatcher encountered an error - // - *(UINT8 *)CommBuffer = COMM_BUFFER_MM_DISPATCH_ERROR; - } + if (*CommBufferSize > sizeof (EFI_STATUS)) { + // + // Set the status of MmDispatcher to CommBuffer + // + *(EFI_STATUS *)CommBuffer = Status; } } diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index ca618c2d..909ad6a7 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -15,14 +15,12 @@ #include #include #include -#include #include // MU_CHANGE: Added MM configuration PPI #include #include #include #include -#include // MU_CHANGE: MM_SUPV: Added MM Supervisor request data structure #include #include @@ -76,29 +74,6 @@ SmmCommunicationCommunicate ( IN OUT UINTN *CommSize ); -// MU_CHANGE: MM_SUPV: Supervisor communication function prototype - -/** - Communicates with a registered handler. - - This function provides a service to send and receive messages from a registered UEFI service. - - @param[in] This The MM_SUPERVISOR_COMMUNICATION_PPI instance. - @param[in] CommBuffer A pointer to the buffer to convey into SMRAM. - @param[in] CommSize The size of the data buffer being passed in.On exit, the size of data - being returned. Zero if the handler does not wish to reply with any data. - - @retval EFI_SUCCESS The message was successfully posted. - @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. -**/ -EFI_STATUS -EFIAPI -SupvCommunicationCommunicate ( - IN CONST MM_SUPERVISOR_COMMUNICATION_PPI *This, - IN OUT VOID *CommBuffer, - IN OUT UINTN *CommSize OPTIONAL - ); - /** Event notification that is fired when a GUIDed Event Group is signaled. @@ -125,30 +100,15 @@ EFI_PEI_SMM_COMMUNICATION_PPI mSmmCommunication = { .Communicate = SmmCommunicationCommunicate }; -// MU_CHANGE: MM_SUPV: Supervisor communication PPI instance -// -// Supervisor MM Communication PPI instance -// -MM_SUPERVISOR_COMMUNICATION_PPI mMmSupvCommunication = { - .Signature = MM_SUPERVISOR_COMM_PPI_SIG, - .Version = MM_SUPERVISOR_COMM_PPI_VER, - .Communicate = SupvCommunicationCommunicate -}; - // // List of PPIs to be installed at the success of MM foundation setup // STATIC EFI_PEI_PPI_DESCRIPTOR mPeiMmIplPpiList[] = { { - EFI_PEI_PPI_DESCRIPTOR_PPI, + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiPeiSmmCommunicationPpiGuid, &mSmmCommunication - }, - { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gPeiMmSupervisorCommunicationPpiGuid, - &mMmSupvCommunication } }; @@ -240,54 +200,6 @@ GetMmramCacheRange ( } while (FoundAdjacentRange); } -// MU_CHANGE: MM_SUPV: MM Supervisor communication protocol, used to query MM policy, -// region unblock, driver dispatching - -/** - Communicates with a registered handler. - - This function provides a service to send and receive messages from a registered UEFI service. - - @param[in] This The MM_SUPERVISOR_COMMUNICATION_PPI instance. - @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM. - @param[in, out] CommSize The size of the data buffer being passed in. On exit, 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 The CommBuffer 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 -SupvCommunicationCommunicate ( - IN CONST MM_SUPERVISOR_COMMUNICATION_PPI *This, - IN OUT VOID *CommBuffer, - IN OUT UINTN *CommSize OPTIONAL - ) -{ - if ((This == NULL) || - (This->Signature != MM_SUPERVISOR_COMM_PPI_SIG) || - (This->Version != MM_SUPERVISOR_COMM_PPI_VER)) - { - return EFI_INVALID_PARAMETER; - } - - return SmmCommunicationCommunicateWorker ( - TRUE, - CommBuffer, - CommSize - ); -} - /** Communicates with a registered handler. @@ -354,159 +266,6 @@ SmmIplGuidedEventNotify ( return SmmIplGuidedEventNotifyWorker (NotifyDescriptor->Guid); } -// MU_CHANGE Starts: MM_SUPV: Will immediately signal MM core to dispatch MM drivers -#define COMM_BUFFER_MM_DISPATCH_ERROR 0x00 -#define COMM_BUFFER_MM_DISPATCH_SUCCESS 0x01 -#define COMM_BUFFER_MM_DISPATCH_RESTART 0x02 -/** - Invokes the MM core to dispatch drivers from inside MM environment. This - function will only be called after MM foundation is successfully set. - - @return Status of the notification. - The status code returned from this function is ignored. -**/ -EFI_STATUS -EFIAPI -MmDriverDispatchNotify ( - VOID - ) -{ - UINTN Size; - EFI_STATUS Status; - - // - // Keep calling the SMM Core Dispatcher until there is no request to restart it. - // - while (TRUE) { - // MU_CHANGE: MM_SUPV: Driver dispatcher command only deals with supervisor - mCommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mMmSupvCommonBuffer; - - // - // Use Guid to initialize EFI_MM_COMMUNICATE_HEADER structure - // Clear the buffer passed into the Software SMI. This buffer will return - // the status of the SMM Core Dispatcher. - // - CopyGuid (&(mCommunicateHeader->HeaderGuid), &gMmSupervisorDriverDispatchGuid); - mCommunicateHeader->MessageLength = 1; - mCommunicateHeader->Data[0] = 0; - - // - // Generate the Software SMI and return the result - // - Size = sizeof (EFI_MM_COMMUNICATE_HEADER); - Status = SupvCommunicationCommunicate (&mMmSupvCommunication, mCommunicateHeader, &Size); - - // - // Return if there is no request to restart the SMM Core Dispatcher - // - if (mCommunicateHeader->Data[0] != COMM_BUFFER_MM_DISPATCH_RESTART) { - return Status; - } else { - ASSERT (FALSE); - } - } - - // Should not be here - return EFI_DEVICE_ERROR; -} - -// MU_CHANGE Ends: MM_SUPV - -// MU_CHANGE: Loaded Fixed Address information is unsupported -// /** -// Get the fixed loading address from image header assigned by build tool. This function only be called -// when Loading module at Fixed address feature enabled. - -// @param ImageContext Pointer to the image context structure that describes the PE/COFF -// image that needs to be examined by this function. -// @retval EFI_SUCCESS An fixed loading address is assigned to this image by build tools . -// @retval EFI_NOT_FOUND The image has no assigned fixed loading address. -// **/ -// EFI_STATUS -// GetPeCoffImageFixLoadingAssignedAddress( -// IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext -// ) -// { -// UINTN SectionHeaderOffset; -// EFI_STATUS Status; -// EFI_IMAGE_SECTION_HEADER SectionHeader; -// EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; -// EFI_PHYSICAL_ADDRESS FixLoadingAddress; -// UINT16 Index; -// UINTN Size; -// UINT16 NumberOfSections; -// EFI_PHYSICAL_ADDRESS MmramBase; -// UINT64 MmCodeSize; -// UINT64 ValueInSectionHeader; -// // -// // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber -// // -// MmCodeSize = EFI_PAGES_TO_SIZE (PcdGet32(PcdLoadFixAddressSmmCodePageNumber)); - -// FixLoadingAddress = 0; -// Status = EFI_NOT_FOUND; -// MmramBase = mLMFAConfigurationTable->SmramBase; -// // -// // Get PeHeader pointer -// // -// ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset); -// SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + -// sizeof (UINT32) + -// sizeof (EFI_IMAGE_FILE_HEADER) + -// ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader; -// NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections; - -// // -// // Get base address from the first section header that doesn't point to code section. -// // -// for (Index = 0; Index < NumberOfSections; Index++) { -// // -// // Read section header from file -// // -// Size = sizeof (EFI_IMAGE_SECTION_HEADER); -// Status = ImageContext->ImageRead ( -// ImageContext->Handle, -// SectionHeaderOffset, -// &Size, -// &SectionHeader -// ); -// if (EFI_ERROR (Status)) { -// return Status; -// } - -// Status = EFI_NOT_FOUND; - -// if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { -// // -// // Build tool saves the offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields in the -// // first section header that doesn't point to code section in image header. And there is an assumption that when the -// // feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers -// // fields should NOT be Zero, or else, these 2 fields should be set to Zero -// // -// ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations); -// if (ValueInSectionHeader != 0) { -// // -// // Found first section header that doesn't point to code section in which build tool saves the -// // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields -// // -// FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(MmramBase + (INT64)ValueInSectionHeader); - -// if (MmramBase + MmCodeSize > FixLoadingAddress && MmramBase <= FixLoadingAddress) { -// // -// // The assigned address is valid. Return the specified loading address -// // -// ImageContext->ImageAddress = FixLoadingAddress; -// Status = EFI_SUCCESS; -// } -// } -// break; -// } -// SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); -// } -// DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r \n", FixLoadingAddress, Status)); -// return Status; -// } - // MU_CHANGE Starts: The MM core address found routine is updated with PEI services /** @@ -1155,20 +914,14 @@ MmIplPeiEntry ( IN CONST EFI_PEI_SERVICES **PeiServices ) { - EFI_STATUS Status; - UINTN Index; - UINT64 MaxSize; - UINTN Size; - UINTN MmramRangeCount; - // UINT64 MmCodeSize; - // EFI_CPU_ARCH_PROTOCOL *CpuArch; - // EFI_STATUS SetAttrStatus; - // EFI_MMRAM_DESCRIPTOR *MmramRangeSmmDriver; - // EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; - EFI_MMRAM_DESCRIPTOR *MmramRanges; - // MU_CHANGE: MM_SUPV: Test supervisor communication before publishing protocol - MM_SUPERVISOR_VERSION_INFO_BUFFER VersionInfo; - MTRR_MEMORY_CACHE_TYPE CacheAttribute; + EFI_STATUS Status; + UINTN Index; + UINT64 MaxSize; + UINTN Size; + UINTN MmramRangeCount; + EFI_MMRAM_DESCRIPTOR *MmramRanges; + MTRR_MEMORY_CACHE_TYPE CacheAttribute; + EFI_MEMORY_DESCRIPTOR CommunicationRegion; Status = PeiServicesRegisterForShadow (FileHandle); @@ -1178,7 +931,7 @@ MmIplPeiEntry ( // MU_CHANGE: MM_SUPV: Initialize Comm buffer from HOBs first Status = InitializeCommunicationBufferFromHob ( - &mMmSupvCommunication.CommunicationRegion + &CommunicationRegion ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "%a Failed to initialize communication buffer from HOBs - %r\n", __func__, Status)); @@ -1332,67 +1085,6 @@ MmIplPeiEntry ( DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM region to load SMM Core\n")); } - // - // Close all SMRAM ranges - // - // MU_CHANGE: Iterate through each MMRAM for PPI instance - for (Index = 0; Index < MmramRangeCount; Index++) { - Status = mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "SMM IPL failed to close SMRAM windows index %d - %r\n", Index, Status)); - ASSERT (FALSE); - return Status; - } - - // - // Print debug message that the SMRAM window is now closed. - // - DEBUG ((DEBUG_INFO, "MM IPL closed SMRAM window index %d\n", Index)); - } - - // MU_CHANGE: MM_SUPV: Locked immediately after closing instead of waiting for ready to lock event - // - // Lock the SMRAM (Note: Locking SMRAM may not be supported on all platforms) - // - for (Index = 0; Index < MmramRangeCount; Index++) { - Status = mSmmAccess->Lock ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); - if (EFI_ERROR (Status)) { - // - // Print error message that the SMRAM failed to lock... - // - DEBUG ((DEBUG_ERROR, "MM IPL could not lock MMRAM (Index %d) after executing MM Core %r\n", Index, Status)); - ASSERT (FALSE); - return Status; - } - - // - // Print debug message that the SMRAM window is now closed. - // - DEBUG ((DEBUG_INFO, "MM IPL locked SMRAM window index %d\n", Index)); - } - - SECURITY_LOCK_REPORT_EVENT ("Lock MMRAM", HARDWARE_LOCK); // MSCHANGE - - // - // Print debug message that the SMRAM window is now locked. - // - DEBUG ((DEBUG_INFO, "SMM IPL locked SMRAM window\n")); - - // MU_CHANGE: MM_SUPV: We are just making sure this communication to supervisor does not fail after setup. - Status = QuerySupervisorVersion (&VersionInfo); - if (EFI_ERROR (Status)) { - return Status; - } - - // MU_CHANGE: MM_SUPV: Added a forced trigger to load all drivers in MM - // - // Trigger to dispatch MM drivers from inside MM - // - if (!EFI_ERROR (Status)) { - Status = MmDriverDispatchNotify (); - DEBUG ((DEBUG_INFO, "MM driver dispatching returned - %r\n", Status)); - } - // // If the SMM Core could not be loaded then close SMRAM window, free allocated // resources, and return an error so SMM IPL will be unloaded. diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c new file mode 100644 index 00000000..8987a8c3 --- /dev/null +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c @@ -0,0 +1,490 @@ +/** @file + MM IPL in PEI that produces MM related PPIs and load the MM Core into MMRAM + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include // MU_CHANGE: MM_SUPV: Added MM Supervisor request data structure +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // MU_CHANGE: BZ3398 +#include // MSCHANGE + +#include "Common/CommonHeader.h" +#include "Common/MmIplCommon.h" +#ifdef MDE_CPU_IA32 + #include "IA32/X64Loader.h" +#endif + +#define SMRAM_CAPABILITIES (EFI_MEMORY_WB | EFI_MEMORY_UC) + +// +// Function prototypes from produced PPIs +// + +/** + 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_PEI_SMM_COMMUNICATION_PPI instance. + @param[in] CommBuffer A pointer to the buffer to convey into SMRAM. + @param[in] CommSize The size of the data buffer being passed in.On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. +**/ +EFI_STATUS +EFIAPI +SmmCommunicationCommunicate ( + IN CONST EFI_PEI_SMM_COMMUNICATION_PPI *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize + ); + +// MU_CHANGE: MM_SUPV: Supervisor communication function prototype + +/** + Communicates with a registered handler. + + This function provides a service to send and receive messages from a registered UEFI service. + + @param[in] This The MM_SUPERVISOR_COMMUNICATION_PPI instance. + @param[in] CommBuffer A pointer to the buffer to convey into SMRAM. + @param[in] CommSize The size of the data buffer being passed in.On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. +**/ +EFI_STATUS +EFIAPI +SupvCommunicationCommunicate ( + IN CONST MM_SUPERVISOR_COMMUNICATION_PPI *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize OPTIONAL + ); + +/** + Event notification that is fired when a GUIDed Event Group is signaled. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @return Status of the notification. + The status code returned from this function is ignored. + +**/ +EFI_STATUS +EFIAPI +SmmIplGuidedEventNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +// MU_CHANGE: MM_SUPV: Supervisor communication PPI instance +// +// Supervisor MM Communication PPI instance +// +MM_SUPERVISOR_COMMUNICATION_PPI mMmSupvCommunication = { + .Signature = MM_SUPERVISOR_COMM_PPI_SIG, + .Version = MM_SUPERVISOR_COMM_PPI_VER, + .Communicate = SupvCommunicationCommunicate +}; + +// +// List of PPIs to be installed at the success of MM foundation setup +// +STATIC EFI_PEI_PPI_DESCRIPTOR mPeiMmIplPpiList[] = +{ + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gPeiMmSupervisorCommunicationPpiGuid, + &mMmSupvCommunication + } +}; + +// +// SMM IPL global variables +// +EFI_PEI_MM_CONTROL_PPI *mSmmControl; +EFI_PEI_MM_ACCESS_PPI *mSmmAccess; +EFI_MMRAM_DESCRIPTOR *mCurrentMmramRange; +EFI_PHYSICAL_ADDRESS mMmramCacheBase; +UINT64 mMmramCacheSize; + +// MU_CHANGE: Loaded Fixed Address information is unsupported +// EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE *mLMFAConfigurationTable = NULL; + +// +// Table of PPI notification and GUIDed Event notifications that the SMM IPL requires +// +STATIC EFI_PEI_NOTIFY_DESCRIPTOR mPeiMmIplNotifyList = +{ + // + // Declare event notification on Exit Boot Services Event Group. This is used to inform the SMM Core + // to notify SMM driver that system enter exit boot services. + // + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + SmmIplGuidedEventNotify +}; + +// MU_CHANGE: Abstracted function implementation of MmControl->Trigger for PEI + +/** + Abstraction layer for MM Control Trigger under various environments (PEI & DXE). + The IPL driver will implement this functionality to be used by MM Communication + routine. + + @retval Others See definition of EFI_MM_ACTIVATE. + + **/ +EFI_STATUS +InternalMmControlTrigger ( + VOID + ) +{ + return mSmmControl->Trigger ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), mSmmControl, NULL, NULL, FALSE, 0); +} + +// MU_CHANGE: MM_SUPV: MM Supervisor communication protocol, used to query MM policy, +// region unblock, driver dispatching + +/** + Communicates with a registered handler. + + This function provides a service to send and receive messages from a registered UEFI service. + + @param[in] This The MM_SUPERVISOR_COMMUNICATION_PPI instance. + @param[in, out] CommBuffer A pointer to the buffer to convey into MMRAM. + @param[in, out] CommSize The size of the data buffer being passed in. On exit, 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 The CommBuffer 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 +SupvCommunicationCommunicate ( + IN CONST MM_SUPERVISOR_COMMUNICATION_PPI *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize OPTIONAL + ) +{ + if ((This == NULL) || + (This->Signature != MM_SUPERVISOR_COMM_PPI_SIG) || + (This->Version != MM_SUPERVISOR_COMM_PPI_VER)) + { + return EFI_INVALID_PARAMETER; + } + + return SmmCommunicationCommunicateWorker ( + TRUE, + CommBuffer, + CommSize + ); +} + +// MU_CHANGE Starts: MM_SUPV: Will immediately signal MM core to dispatch MM drivers + +/** + Invokes the MM core to dispatch drivers from inside MM environment. This + function will only be called after MM foundation is successfully set. + + @return Status of the notification. + The status code returned from this function is ignored. +**/ +EFI_STATUS +EFIAPI +MmDriverDispatchNotify ( + VOID + ) +{ + UINTN Size; + EFI_STATUS Status; + + // MU_CHANGE: MM_SUPV: Driver dispatcher command only deals with supervisor + mCommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mMmSupvCommonBuffer; + + // + // Use Guid to initialize EFI_MM_COMMUNICATE_HEADER structure + // Clear the buffer passed into the Software SMI. This buffer will return + // the status of the SMM Core Dispatcher. + // + CopyGuid (&(mCommunicateHeader->HeaderGuid), &gMmSupervisorDriverDispatchGuid); + mCommunicateHeader->MessageLength = 1; + mCommunicateHeader->Data[0] = 0; + + // + // Generate the Software SMI and return the result + // + Size = sizeof (EFI_MM_COMMUNICATE_HEADER); + Status = SupvCommunicationCommunicate (&mMmSupvCommunication, mCommunicateHeader, &Size); + + // + // Return if there is no request to restart the MM Core Dispatcher + // + if (Status != EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "MM Driver Dispatch failed (%r)\n", Status)); + return Status; + } + + // + // Get the status returned from the MM Core Dispatcher + // + if (Size >= sizeof (EFI_STATUS)) { + Status = *(EFI_STATUS*)mCommunicateHeader->Data; + } else { + Status = EFI_DEVICE_ERROR; + } + + return Status; +} + +// MU_CHANGE Ends: MM_SUPV + +/** + The Entry Point for PEI MM IPL + + Load MM Core into MMRAM, register MM Core entry point for SMIs, install + MM Communication PPI (both for user and supervisor), and register for the + critical events required to coordinate between PEI and MM environments. + + @param[in] FileHandle Not used. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval Other Some error occurred when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +MmIplPeiEntry ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + UINTN Index; + UINT64 MaxSize; + UINTN Size; + UINTN MmramRangeCount; + EFI_MMRAM_DESCRIPTOR *MmramRanges; + MM_SUPERVISOR_VERSION_INFO_BUFFER VersionInfo; + + Status = PeiServicesRegisterForShadow (FileHandle); + + if (!EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + // MU_CHANGE: MM_SUPV: Initialize Comm buffer from HOBs first + Status = InitializeCommunicationBufferFromHob ( + &mMmSupvCommunication.CommunicationRegion + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a Failed to initialize communication buffer from HOBs - %r\n", __func__, Status)); + return Status; + } + + // + // Get SMM Access PPI + // + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiMmAccessPpiGuid, + 0, + NULL, + (VOID **)&mSmmAccess + ); + ASSERT_EFI_ERROR (Status); + + // + // Get SMM Control PPI + // + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiMmControlPpiGuid, + 0, + NULL, + (VOID **)&mSmmControl + ); + ASSERT_EFI_ERROR (Status); + + // + // Open all SMRAM ranges + // + // MU_CHANGE Starts: Need to iterate through all MMRAMs to open one at a time for PPI interface + Size = 0; + Status = mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, &Size, NULL); + if (Status != EFI_BUFFER_TOO_SMALL) { + // This is not right... + ASSERT (FALSE); + return EFI_DEVICE_ERROR; + } + + MmramRanges = AllocatePool (Size); + if (MmramRanges == NULL) { + ASSERT (MmramRanges != NULL); + return EFI_OUT_OF_RESOURCES; + } + + Status = mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, &Size, MmramRanges); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SMM IPL failed to get SMRAM capabilities - %r\n", Status)); + ASSERT (FALSE); + return Status; + } + + MmramRangeCount = Size / sizeof (EFI_MMRAM_DESCRIPTOR); + // MU_CHANGE Ends + + // + // Find the largest SMRAM range between 1MB and 4GB that is at least 256KB - 4K in size + // + mCurrentMmramRange = NULL; + for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; (UINT64)Index < MmramRangeCount; Index++) { + // + // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization + // + if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { + continue; + } + + if (MmramRanges[Index].CpuStart >= BASE_1MB) { + if ((MmramRanges[Index].CpuStart + MmramRanges[Index].PhysicalSize - 1) <= MAX_ADDRESS) { + if (MmramRanges[Index].PhysicalSize >= MaxSize) { + MaxSize = MmramRanges[Index].PhysicalSize; + mCurrentMmramRange = &MmramRanges[Index]; + } + } + } + } + + // + // Close all SMRAM ranges + // + // MU_CHANGE: Iterate through each MMRAM for PPI instance + for (Index = 0; Index < MmramRangeCount; Index++) { + Status = mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SMM IPL failed to close SMRAM windows index %d - %r\n", Index, Status)); + ASSERT (FALSE); + return Status; + } + + // + // Print debug message that the SMRAM window is now closed. + // + DEBUG ((DEBUG_INFO, "MM IPL closed SMRAM window index %d\n", Index)); + } + + // MU_CHANGE: MM_SUPV: Locked immediately after closing instead of waiting for ready to lock event + // + // Lock the SMRAM (Note: Locking SMRAM may not be supported on all platforms) + // + for (Index = 0; Index < MmramRangeCount; Index++) { + Status = mSmmAccess->Lock ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); + if (EFI_ERROR (Status)) { + // + // Print error message that the SMRAM failed to lock... + // + DEBUG ((DEBUG_ERROR, "MM IPL could not lock MMRAM (Index %d) after executing MM Core %r\n", Index, Status)); + ASSERT (FALSE); + return Status; + } + + // + // Print debug message that the SMRAM window is now closed. + // + DEBUG ((DEBUG_INFO, "MM IPL locked SMRAM window index %d\n", Index)); + } + + SECURITY_LOCK_REPORT_EVENT ("Lock MMRAM", HARDWARE_LOCK); // MSCHANGE + + // + // Print debug message that the SMRAM window is now locked. + // + DEBUG ((DEBUG_INFO, "SMM IPL locked SMRAM window\n")); + + // MU_CHANGE: MM_SUPV: We are just making sure this communication to supervisor does not fail after setup. + Status = QuerySupervisorVersion (&VersionInfo); + if (EFI_ERROR (Status)) { + return Status; + } + + // MU_CHANGE: MM_SUPV: Added a forced trigger to load all drivers in MM + // + // Trigger to dispatch MM drivers from inside MM + // + if (!EFI_ERROR (Status)) { + Status = MmDriverDispatchNotify (); + DEBUG ((DEBUG_INFO, "MM driver dispatching returned - %r\n", Status)); + } + + // + // If the SMM Core could not be loaded then close SMRAM window, free allocated + // resources, and return an error so SMM IPL will be unloaded. + // + if ((mCurrentMmramRange == NULL) || EFI_ERROR (Status)) { + // + // Free all allocated resources + // + FreePool ((VOID *)MmramRanges); + + return EFI_UNSUPPORTED; + } + + // + // Install MM Communication and Supervisor MM Communication PPI + // + Status = (*PeiServices)->InstallPpi (PeiServices, mPeiMmIplPpiList); + ASSERT_EFI_ERROR (Status); + + // + // Create the set of ppi and event notifications that the SMM IPL requires + // + Status = (*PeiServices)->NotifyPpi (PeiServices, &mPeiMmIplNotifyList); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf new file mode 100644 index 00000000..38b32f11 --- /dev/null +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf @@ -0,0 +1,88 @@ +## @file +# This module provide an MM CIS compliant implementation of MM IPL in PEI. +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) Microsoft Corporation. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MmPeiSupport + FILE_GUID = B525E664-18E1-4EB3-806E-078F75058454 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = MmPeiSupportEntry + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + MmPeiSupport.c + Common/MmIplCommon.c + Common/MmIplCommon.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec + UefiCpuPkg/UefiCpuPkg.dec + MmSupervisorPkg/MmSupervisorPkg.dec + +[LibraryClasses] + PeimEntryPoint + BaseLib + BaseMemoryLib + PeCoffLib + CacheMaintenanceLib + MemoryAllocationLib + DebugLib + PcdLib + ReportStatusCodeLib + SafeIntLib #MU_CHANGE: BZ3398 + SecurityLockAuditLib #MSCHANGE + PeCoffGetEntryPointLib + MtrrLib #MU_CHANGE: MM_SUPV: MMRAM region cachability during init + PerformanceLib #MU_CHANGE: MM_SUPV: Added performance data points + PeiServicesLib #MU_CHANGE: Add PeiServicesLib to INF + HobLib #MU_CHANGE: Add HobLib to INF + PanicLib #MU_CHANGE: Add PanicLib to INF + +[Ppis] + gEfiPeiSmmCommunicationPpiGuid ## PRODUCES + gEfiPeiMmAccessPpiGuid ## CONSUMES + gEfiPeiMmControlPpiGuid ## CONSUMES + gPeiMmSupervisorCommunicationPpiGuid ## PRODUCES + gEfiPeiLoadFilePpiGuid ## CONSUMES + gEfiEndOfPeiSignalPpiGuid ## CONSUMES + gEfiPeiMmConfigurationPpi ## CONSUMES # MU_CHANGE: Added MM Configuration PPI + +[Guids] + # gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported + gMmCoreMmProfileGuid ## SOMETIMES_CONSUMES + gMmCommonRegionHobGuid ## PRODUCES + gMmSupervisorDriverDispatchGuid ## PRODUCES ## Invoke driver dispatcher + gMmSupervisorRequestHandlerGuid ## CONSUMES + gEfiMmPeiMmramMemoryReserveGuid ## CONSUMES + gEfiSmmSmramMemoryGuid ## CONSUMES + gMmCommBufferHobGuid ## CONSUMES + gMmSupervisorCoreGuid ## CONSUMES + +[Pcd] + # gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported + gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES + gMmSupervisorPkgTokenSpaceGuid.PcdMmIplX64RelayFile ## CONSUMES + gMmSupervisorPkgTokenSpaceGuid.PcdPeiMmInitLongModeStackSize ## CONSUMES + +[Depex] + gEfiPeiMmAccessPpiGuid AND gEfiPeiMmControlPpiGuid AND gMmCommunicationBufferReadyPpiGuid From e09917e7a7444d7b93f447c88a1cf5f66d51677f Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Wed, 8 Oct 2025 23:29:02 -0700 Subject: [PATCH 11/36] breaking up ipl and mmsupv suppot --- .../Drivers/MmPeiLaunchers/MmIplPei.c | 1 + .../Drivers/MmPeiLaunchers/MmPeiSupport.c | 45 +------------------ 2 files changed, 3 insertions(+), 43 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index 909ad6a7..33b55944 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c index 8987a8c3..c7a122ff 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c @@ -17,6 +17,7 @@ #include #include +#include #include #include // MU_CHANGE: MM_SUPV: Added MM Supervisor request data structure #include @@ -91,25 +92,6 @@ SupvCommunicationCommunicate ( IN OUT UINTN *CommSize OPTIONAL ); -/** - Event notification that is fired when a GUIDed Event Group is signaled. - - @param PeiServices Indirect reference to the PEI Services Table. - @param NotifyDescriptor Address of the notification descriptor data structure. - @param Ppi Address of the PPI that was installed. - - @return Status of the notification. - The status code returned from this function is ignored. - -**/ -EFI_STATUS -EFIAPI -SmmIplGuidedEventNotify ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, - IN VOID *Ppi - ); - // MU_CHANGE: MM_SUPV: Supervisor communication PPI instance // // Supervisor MM Communication PPI instance @@ -141,23 +123,6 @@ EFI_MMRAM_DESCRIPTOR *mCurrentMmramRange; EFI_PHYSICAL_ADDRESS mMmramCacheBase; UINT64 mMmramCacheSize; -// MU_CHANGE: Loaded Fixed Address information is unsupported -// EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE *mLMFAConfigurationTable = NULL; - -// -// Table of PPI notification and GUIDed Event notifications that the SMM IPL requires -// -STATIC EFI_PEI_NOTIFY_DESCRIPTOR mPeiMmIplNotifyList = -{ - // - // Declare event notification on Exit Boot Services Event Group. This is used to inform the SMM Core - // to notify SMM driver that system enter exit boot services. - // - (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiEndOfPeiSignalPpiGuid, - SmmIplGuidedEventNotify -}; - // MU_CHANGE: Abstracted function implementation of MmControl->Trigger for PEI /** @@ -298,7 +263,7 @@ MmDriverDispatchNotify ( **/ EFI_STATUS EFIAPI -MmIplPeiEntry ( +MmPeiSupportEntry ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) @@ -480,11 +445,5 @@ MmIplPeiEntry ( Status = (*PeiServices)->InstallPpi (PeiServices, mPeiMmIplPpiList); ASSERT_EFI_ERROR (Status); - // - // Create the set of ppi and event notifications that the SMM IPL requires - // - Status = (*PeiServices)->NotifyPpi (PeiServices, &mPeiMmIplNotifyList); - ASSERT_EFI_ERROR (Status); - return EFI_SUCCESS; } From 0eaaf3b0b434f29bca80b46c42d383ce727ab142 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 3 Nov 2025 16:20:21 -0800 Subject: [PATCH 12/36] Adding end of PEI handler --- .../MmSupervisorRing3Broker.c | 41 +++++++++++++++++++ .../MmSupervisorRing3Broker.h | 9 ++++ .../MmSupervisorRing3Broker.inf | 1 + 3 files changed, 51 insertions(+) diff --git a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.c b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.c index 6677e86f..c732eacb 100644 --- a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.c +++ b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.c @@ -30,6 +30,7 @@ // MM_SHIM_MMI_HANDLERS mMmShimMmiHandlers[] = { { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE }, + { MmEndOfPeiHandler, &gEfiMmEndOfPeiProtocol, NULL, FALSE }, { MmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE }, { MmExitBootServiceHandler, &gEfiEventExitBootServicesGuid, NULL, FALSE }, { MmReadyToBootHandler, &gEfiEventReadyToBootGuid, NULL, FALSE }, @@ -242,6 +243,46 @@ MmReadyToLockHandler ( return Status; } +/** + Software MMI handler that is called when the EndOfPei event is signaled. + This function installs the MM EndOfPei Protocol so MM Drivers are informed that + EndOfPei event is signaled. + + @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister(). + @param Context Points to an optional handler context which was specified when the handler was registered. + @param CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-MM environment into an MM environment. + @param CommBufferSize The size of the CommBuffer. + + @return Status Code + +**/ +EFI_STATUS +EFIAPI +MmEndOfPeiHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_HANDLE MmHandle; + + DEBUG ((DEBUG_INFO, "MmEndOfPeiHandler\n")); + // + // Install MM EndOfDxe protocol + // + MmHandle = NULL; + Status = MmInstallUserProtocolInterface ( + &MmHandle, + &gEfiMmEndOfPeiProtocol, + EFI_NATIVE_INTERFACE, + NULL + ); + return Status; +} + /** Software MMI handler that is called when the EndOfDxe event is signaled. This function installs the MM EndOfDxe Protocol so MM Drivers are informed that diff --git a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.h b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.h index c8c8e791..1e8a7d65 100644 --- a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.h +++ b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.h @@ -287,6 +287,15 @@ MmReadyToLockHandler ( IN OUT UINTN *CommBufferSize OPTIONAL ); +EFI_STATUS +EFIAPI +MmEndOfPeiHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ); + EFI_STATUS EFIAPI MmEndOfDxeHandler ( diff --git a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.inf b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.inf index 7e975337..ab9efa25 100644 --- a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.inf +++ b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.inf @@ -64,6 +64,7 @@ gEfiDxeMmReadyToLockProtocolGuid # PRODUCES gEfiMmReadyToLockProtocolGuid # PRODUCES gEfiMmEndOfDxeProtocolGuid # PRODUCES + gEfiMmEndOfPeiProtocol # PRODUCES [Guids] gEfiEndOfDxeEventGroupGuid # PRODUCES From a40251cab3dad4444bd76875079d77d060d02180 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 3 Nov 2025 16:23:35 -0800 Subject: [PATCH 13/36] Building allocation module hob just like the edk2 style --- .../Drivers/MmPeiLaunchers/MmIplPei.c | 72 ++----------------- 1 file changed, 6 insertions(+), 66 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index 33b55944..74ab9fef 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -462,62 +462,6 @@ MmIplAllocateMmramPage ( return Allocated->CpuStart; } -/** - Builds a HOB for a loaded PE32 module. - - This function builds a HOB for a loaded PE32 module. - It can only be invoked during PEI phase; - If physical address of the Module is not 4K aligned, then ASSERT(). - If new HOB buffer is NULL, then ASSERT(). - - @param[in] Hob The pointer of new HOB buffer. - @param[in, out] HobBufferSize The available size of the HOB buffer when as input. - The used size of when as output. - @param[in] ModuleName The GUID File Name of the module. - @param[in] Base The 64 bit physical address of the module. - @param[in] Length The length of the module in bytes. - @param[in] EntryPoint The 64 bit physical address of the module entry point. - -**/ -EFI_STATUS -MmIplBuildMmCoreAllocationHob ( - IN CONST EFI_GUID *ModuleName, - IN EFI_PHYSICAL_ADDRESS Base, - IN UINT64 Length, - IN EFI_PHYSICAL_ADDRESS EntryPoint - ) -{ - EFI_STATUS Status; - - if (!IS_ALIGNED (Base, EFI_PAGE_SIZE) || !IS_ALIGNED (Length, EFI_PAGE_SIZE)) { - Status = EFI_INVALID_PARAMETER; - goto Exit; - } - - if ((EntryPoint < Base) || (EntryPoint >= Base + Length)) { - Status = EFI_INVALID_PARAMETER; - goto Exit; - } - - // TODO: This deviates from the EDK2 implementation which uses - // the build module HOB. - BuildMemoryAllocationHob ( - Base, - Length, - EfiReservedMemoryType - ); - - TagMemoryAllocationHobWithGuid ( - Base, - ModuleName - ); - - Status = EFI_SUCCESS; - -Exit: - return Status; -} - // MU_CHANGE Ends /** @@ -623,16 +567,12 @@ ExecuteMmCoreFromMmram ( // MU_CHANGE Starts: To load x64 MM foundation, mode switch is needed EntryPoint = (STANDALONE_MM_FOUNDATION_ENTRY_POINT)(UINTN)ImageContext.EntryPoint; - Status = MmIplBuildMmCoreAllocationHob ( - &gMmSupervisorCoreGuid, - ImageContext.ImageAddress, - (UINT64)EFI_PAGES_TO_SIZE (PageCount), - (EFI_PHYSICAL_ADDRESS)(UINTN)ImageContext.EntryPoint - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Failed to build MM core module HOB - %r...\n", __func__, Status)); - goto Exit; - } + BuildModuleHob ( + &gMmSupervisorCoreGuid, + ImageContext.ImageAddress, + (UINT64)EFI_PAGES_TO_SIZE (PageCount), + (EFI_PHYSICAL_ADDRESS)(UINTN)ImageContext.EntryPoint + ); HobStart = GetHobList (); #ifdef MDE_CPU_IA32 From d4c41eca66837521b06445420f960e6bb4762e1f Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 3 Nov 2025 16:24:07 -0800 Subject: [PATCH 14/36] look up the hob just like edk2 style --- MmSupervisorPkg/Core/MmSupervisorCore.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.c b/MmSupervisorPkg/Core/MmSupervisorCore.c index 9494bd10..76427c86 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.c +++ b/MmSupervisorPkg/Core/MmSupervisorCore.c @@ -675,12 +675,29 @@ MmCoreInstallLoadedImage ( EFI_PEI_HOB_POINTERS Hob; // - // TODO: This deviates from the EDK2 implementation which uses the memory allocation - // module to retrieve the memory allocation HOB. // Searching for Memory Allocation HOB // Hob.Raw = GetHobList (); - Hob.Raw = GetNextMemoryAllocationGuidHob (&gMmSupervisorCoreGuid, Hob.Raw); + while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) { + // + // Find MM Core HOB + // + if (CompareGuid ( + &Hob.MemoryAllocationModule->MemoryAllocationHeader.Name, + &gEfiHobMemoryAllocModuleGuid + )) + { + if (CompareGuid (&Hob.MemoryAllocationModule->ModuleName, &gEfiCallerIdGuid)) { + break; + } + } + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + if (Hob.Raw == NULL) { + return; + } if (Hob.Raw == NULL) { DEBUG ((DEBUG_ERROR, "MM Core Memory Allocation HOB not found!\n")); From 814e2a370749db139aee1273214ef3fc7a8237ad Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 13:03:42 -0800 Subject: [PATCH 15/36] revert some changes --- .../Core/Request/UpdateCommBuffer.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/MmSupervisorPkg/Core/Request/UpdateCommBuffer.c b/MmSupervisorPkg/Core/Request/UpdateCommBuffer.c index 4cf311af..c8f36926 100644 --- a/MmSupervisorPkg/Core/Request/UpdateCommBuffer.c +++ b/MmSupervisorPkg/Core/Request/UpdateCommBuffer.c @@ -48,25 +48,25 @@ VerifyandMoveUnblockedPages ( EFI_STATUS Status; if ((NewMemParam == NULL) || (OldMemParam == NULL)) { - DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are NULL - %p and %p!\n", __func__, NewMemParam, OldMemParam)); + DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are NULL - %p and %p!\n", __FUNCTION__, NewMemParam, OldMemParam)); Status = EFI_INVALID_PARAMETER; goto Done; } if (NewMemParam->MemoryDescriptor.NumberOfPages != OldMemParam->MemoryDescriptor.NumberOfPages) { - DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different sizes, this is not allowed!\n", __func__)); + DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different sizes, this is not allowed!\n", __FUNCTION__)); Status = EFI_SECURITY_VIOLATION; goto Done; } if (NewMemParam->MemoryDescriptor.Attribute != OldMemParam->MemoryDescriptor.Attribute) { - DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different attributes, this is not allowed!\n", __func__)); + DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different attributes, this is not allowed!\n", __FUNCTION__)); Status = EFI_SECURITY_VIOLATION; goto Done; } if (NewMemParam->MemoryDescriptor.Type != OldMemParam->MemoryDescriptor.Type) { - DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different types, this is not allowed!\n", __func__)); + DEBUG ((DEBUG_ERROR, "%a - Incoming buffers are of different types, this is not allowed!\n", __FUNCTION__)); Status = EFI_SECURITY_VIOLATION; goto Done; } @@ -74,13 +74,13 @@ VerifyandMoveUnblockedPages ( // Okay, again, enough complaints, now get to work. Status = ProcessUnblockPages (NewMemParam); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to unblock the requested new communicate buffers - %r!\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to unblock the requested new communicate buffers - %r!\n", __FUNCTION__, Status)); goto Done; } Status = ProcessBlockPages (OldMemParam); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to block memory %r!\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to block memory %r!\n", __FUNCTION__, Status)); goto Done; } @@ -123,14 +123,14 @@ ProcessUpdateCommBufferRequest ( DEBUG (( DEBUG_ERROR, "%a - Comm buffer update requested after ready to lock, will not proceed!\n", - __func__ + __FUNCTION__ )); return EFI_ACCESS_DENIED; } // Some more sanity checks here if (UpdateCommBuffer == NULL) { - DEBUG ((DEBUG_ERROR, "%a - Invalid parameter detected - %p!\n", __func__, UpdateCommBuffer)); + DEBUG ((DEBUG_ERROR, "%a - Invalid parameter detected - %p!\n", __FUNCTION__, UpdateCommBuffer)); return EFI_INVALID_PARAMETER; } @@ -142,7 +142,7 @@ ProcessUpdateCommBufferRequest ( CopyMem (&(MmCoreDataDesc.MemoryDescriptor), &(mMmSupervisorAccessBuffer[Index]), sizeof (MmCoreDataDesc.MemoryDescriptor)); Status = VerifyandMoveUnblockedPages (&UpdateCommBuffer->NewCommBuffers[Index], &MmCoreDataDesc); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to moved unblocked buffer (%d) - %r!\n", __func__, Index, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to moved unblocked buffer (%d) - %r!\n", __FUNCTION__, Index, Status)); goto Done; } @@ -157,7 +157,7 @@ ProcessUpdateCommBufferRequest ( MmCoreDataDesc.MemoryDescriptor.Attribute = EFI_MEMORY_XP | EFI_MEMORY_SP; Status = VerifyandMoveUnblockedPages (&UpdateCommBuffer->NewMmCoreData, &MmCoreDataDesc); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to moved unblocked buffer (%d) - %r!\n", __func__, Index, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to moved unblocked buffer (%d) - %r!\n", __FUNCTION__, Index, Status)); goto Done; } From a1660479bb3a1c550aca3e04b8b1f4b056387ad8 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 13:05:10 -0800 Subject: [PATCH 16/36] how about this? --- MmSupervisorPkg/Core/MmSupervisorCore.c | 42 ++++++++++++------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.c b/MmSupervisorPkg/Core/MmSupervisorCore.c index 15b74fa7..07dd6ea7 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.c +++ b/MmSupervisorPkg/Core/MmSupervisorCore.c @@ -226,7 +226,7 @@ PrepareCommonBuffers ( ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to allocate internal buffer copy, please consider adjust TSEG size... - %r\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to allocate internal buffer copy, please consider adjust TSEG size... - %r\n", __FUNCTION__, Status)); goto Exit; } @@ -335,7 +335,7 @@ PrepareCommonBuffers ( ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to allocate internal buffer copy, please consider adjust TSEG size... - %r\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to allocate internal buffer copy, please consider adjust TSEG size... - %r\n", __FUNCTION__, Status)); goto Exit; } @@ -343,7 +343,7 @@ PrepareCommonBuffers ( DEBUG (( DEBUG_INFO, "%a - Populating MM Access Buffer Type %d to 0x%p with 0x%x pages\n", - __func__, + __FUNCTION__, MM_USER_BUFFER_T, mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].PhysicalStart, mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages @@ -351,7 +351,7 @@ PrepareCommonBuffers ( mMmCommMailboxBufferStatus = (MM_COMM_BUFFER_STATUS*)(UINTN)UserCommRegionHob->Status; if (mMmCommMailboxBufferStatus == NULL) { - DEBUG ((DEBUG_ERROR, "%a - Invalid MM Communication Buffer Status pointer!\n", __func__)); + DEBUG ((DEBUG_ERROR, "%a - Invalid MM Communication Buffer Status pointer!\n", __FUNCTION__)); Status = EFI_INVALID_PARAMETER; goto Exit; } @@ -364,13 +364,13 @@ PrepareCommonBuffers ( ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to allocate supervisor to user buffer, cannot continue...\n", __func__)); + DEBUG ((DEBUG_ERROR, "%a - Failed to allocate supervisor to user buffer, cannot continue...\n", __FUNCTION__)); goto Exit; } Exit: if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to prepare communicate buffer for Standalone MM environment... - %r\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to prepare communicate buffer for Standalone MM environment... - %r\n", __FUNCTION__, Status)); ZeroMem (mMmSupervisorAccessBuffer, sizeof (mMmSupervisorAccessBuffer)); ZeroMem (mMmSupervisorAccessBuffer, sizeof (mMmSupervisorAccessBuffer)); } @@ -832,7 +832,7 @@ DiscoverStandaloneMmDriversInFvHobs ( DEBUG (( DEBUG_INFO, "[%a] Found FV HOB referencing FV at 0x%x. Size is 0x%x.\n", - __func__, + __FUNCTION__, (UINTN)FwVolHeader, FwVolHeader->FvLength )); @@ -840,7 +840,7 @@ DiscoverStandaloneMmDriversInFvHobs ( ExtHeaderOffset = ReadUnaligned16 (&FwVolHeader->ExtHeaderOffset); if (ExtHeaderOffset != 0) { ExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FwVolHeader + ExtHeaderOffset); - DEBUG ((DEBUG_INFO, "[%a] FV GUID = {%g}.\n", __func__, &ExtHeader->FvName)); + DEBUG ((DEBUG_INFO, "[%a] FV GUID = {%g}.\n", __FUNCTION__, &ExtHeader->FvName)); } // @@ -859,7 +859,7 @@ DiscoverStandaloneMmDriversInFvHobs ( DEBUG (( DEBUG_INFO, "[%a] Discovered Standalone MM Core [%g] in FV at 0x%x.\n", - __func__, + __FUNCTION__, &gEfiCallerIdGuid, (UINTN)FwVolHeader )); @@ -877,7 +877,7 @@ DiscoverStandaloneMmDriversInFvHobs ( DEBUG (( DEBUG_INFO, "[%a] Adding Standalone MM drivers in FV at 0x%x to the dispatch list.\n", - __func__, + __FUNCTION__, (UINTN)FwVolHeader )); Status = MmCoreFfsFindMmDriver (FwVolHeader); @@ -927,7 +927,7 @@ InitializePolicy ( DEBUG (( DEBUG_ERROR, "[%a] Failed to locate firmware policy file from given FV - %r\n", - __func__, + __FUNCTION__, Status )); break; @@ -940,7 +940,7 @@ InitializePolicy ( DEBUG (( DEBUG_INFO, "[%a] Discovered policy file in FV at 0x%p.\n", - __func__, + __FUNCTION__, FileHeader )); @@ -954,7 +954,7 @@ InitializePolicy ( DEBUG (( DEBUG_ERROR, "[%a] Failed to find raw section from discovered policy file - %r\n", - __func__, + __FUNCTION__, Status )); break; @@ -965,7 +965,7 @@ InitializePolicy ( DEBUG (( DEBUG_ERROR, "[%a] Policy data size 0x%x > blob size 0x%x.\n", - __func__, + __FUNCTION__, PolicySize, SectionDataSize )); @@ -979,7 +979,7 @@ InitializePolicy ( DEBUG (( DEBUG_ERROR, "[%a] Cannot allocate page for firmware provided policy - %r\n", - __func__, + __FUNCTION__, Status )); break; @@ -996,7 +996,7 @@ InitializePolicy ( } while (TRUE); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Unable to locate a valid firmware policy from given FV, bail here - %r\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a Unable to locate a valid firmware policy from given FV, bail here - %r\n", __FUNCTION__, Status)); ASSERT_EFI_ERROR (Status); goto Done; } @@ -1004,14 +1004,14 @@ InitializePolicy ( // Prepare the buffer for Mem policy snapshot, it will be compared against when non-MM entity requested Status = AllocateMemForPolicySnapshot (&MemPolicySnapshot); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Failed to allocate buffer for memory policy snapshot - %r\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a Failed to allocate buffer for memory policy snapshot - %r\n", __FUNCTION__, Status)); ASSERT_EFI_ERROR (Status); goto Done; } Status = SecurityPolicyCheck (FirmwarePolicy); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Policy check failed on policy blob from firmware - %r\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a Policy check failed on policy blob from firmware - %r\n", __FUNCTION__, Status)); ASSERT_EFI_ERROR (Status); goto Done; } @@ -1197,14 +1197,14 @@ MmSupervisorMain ( Status = InitializeMmSupervisorTestAgents (); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Failed to initialize test agents - Status %d\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a Failed to initialize test agents - Status %d\n", __FUNCTION__, Status)); ASSERT (FALSE); goto Exit; } Status = PrepareCommonBuffers (); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Failed to prepare comm buffer - Status %d\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a Failed to prepare comm buffer - Status %d\n", __FUNCTION__, Status)); ASSERT (FALSE); goto Exit; } @@ -1231,7 +1231,7 @@ MmSupervisorMain ( Exit: if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a Standalone MM foundation not properly set, system may not boot - %r!\n", __func__, Status)); + DEBUG ((DEBUG_ERROR, "%a Standalone MM foundation not properly set, system may not boot - %r!\n", __FUNCTION__, Status)); } return Status; From 7443b3aef2116568e4ef4ac4ec2b070dccf6f795 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 13:08:39 -0800 Subject: [PATCH 17/36] revert more --- MmSupervisorPkg/Core/MmSupervisorCore.c | 3 +-- MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c | 1 - MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.c b/MmSupervisorPkg/Core/MmSupervisorCore.c index 07dd6ea7..6f7cb785 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.c +++ b/MmSupervisorPkg/Core/MmSupervisorCore.c @@ -226,7 +226,7 @@ PrepareCommonBuffers ( ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to allocate internal buffer copy, please consider adjust TSEG size... - %r\n", __FUNCTION__, Status)); + DEBUG ((DEBUG_ERROR, "%a - Failed to allocate internal buffer copy, please consider adjust TSEG size... - %r\n", __func__, Status)); goto Exit; } @@ -372,7 +372,6 @@ PrepareCommonBuffers ( if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a - Failed to prepare communicate buffer for Standalone MM environment... - %r\n", __FUNCTION__, Status)); ZeroMem (mMmSupervisorAccessBuffer, sizeof (mMmSupervisorAccessBuffer)); - ZeroMem (mMmSupervisorAccessBuffer, sizeof (mMmSupervisorAccessBuffer)); } return Status; diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c index bca9bd7a..e219ac00 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/Common/MmIplCommon.c @@ -137,7 +137,6 @@ SmmCommunicationCommunicateWorker ( DEBUG ((DEBUG_INFO, "SmmCommunicationCommunicateWorker: Using User Communicate Buffer - %p, %p, %x\n", CommunicateHeader, CommunicateBufferPhysical, TempCommSize)); } - mMmCommBufferStatus->TalkToSupervisor = TalkToSupervisor; mMmCommBufferStatus->TalkToSupervisor = TalkToSupervisor; diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index 299298c6..c007dd5e 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -22,8 +22,8 @@ #include #include #include +#include // MU_CHANGE: MM_SUPV: Added MM Supervisor request data structure #include -#include #include #include From 4f44bdcce8a9aa3cd2de5e88a7ee6ba01fce76e7 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 15:59:02 -0800 Subject: [PATCH 18/36] more changes --- MmSupervisorPkg/Core/MmSupervisorCore.h | 1 - .../Drivers/MmPeiLaunchers/MmIplPei.c | 1 - MmSupervisorPkg/Include/Guid/MmDispatch.h | 17 ----------------- 3 files changed, 19 deletions(-) delete mode 100644 MmSupervisorPkg/Include/Guid/MmDispatch.h diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.h b/MmSupervisorPkg/Core/MmSupervisorCore.h index 98d6cb8a..d18911c8 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.h +++ b/MmSupervisorPkg/Core/MmSupervisorCore.h @@ -33,7 +33,6 @@ #include #include #include -#include #include #include diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index c007dd5e..ab5f4b18 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include // MU_CHANGE: MM_SUPV: Added MM Supervisor request data structure diff --git a/MmSupervisorPkg/Include/Guid/MmDispatch.h b/MmSupervisorPkg/Include/Guid/MmDispatch.h deleted file mode 100644 index 4eb90339..00000000 --- a/MmSupervisorPkg/Include/Guid/MmDispatch.h +++ /dev/null @@ -1,17 +0,0 @@ -/** @file - Common definitions related to the MM dispatcher. - - Copyright (c) Microsoft Corporation. - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef MM_DISPATCH_H_ -#define MM_DISPATCH_H_ - -#define COMM_BUFFER_MM_DISPATCH_ERROR 0x00 -#define COMM_BUFFER_MM_DISPATCH_SUCCESS 0x01 -#define COMM_BUFFER_MM_DISPATCH_RESTART 0x02 - -#endif From 042119f97da2ff80ebe7d42fa2d57f287e297b2e Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 17:09:38 -0800 Subject: [PATCH 19/36] revert seom change --- MmSupervisorPkg/Core/MmSupervisorCore.c | 30 ------------------------- 1 file changed, 30 deletions(-) diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.c b/MmSupervisorPkg/Core/MmSupervisorCore.c index 6f7cb785..afa6b923 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.c +++ b/MmSupervisorPkg/Core/MmSupervisorCore.c @@ -326,36 +326,6 @@ PrepareCommonBuffers ( goto Exit; } - Status = MmAllocatePages ( - AllocateAnyPages, - EfiRuntimeServicesData, - UserCommRegionHob->NumberOfPages, - (EFI_PHYSICAL_ADDRESS *)&mInternalCommBufferCopy[MM_USER_BUFFER_T] - ); - - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a - Failed to allocate internal buffer copy, please consider adjust TSEG size... - %r\n", __FUNCTION__, Status)); - goto Exit; - } - - mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].VirtualStart = 0; - DEBUG (( - DEBUG_INFO, - "%a - Populating MM Access Buffer Type %d to 0x%p with 0x%x pages\n", - __FUNCTION__, - MM_USER_BUFFER_T, - mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].PhysicalStart, - mMmSupervisorAccessBuffer[MM_USER_BUFFER_T].NumberOfPages - )); - - mMmCommMailboxBufferStatus = (MM_COMM_BUFFER_STATUS*)(UINTN)UserCommRegionHob->Status; - if (mMmCommMailboxBufferStatus == NULL) { - DEBUG ((DEBUG_ERROR, "%a - Invalid MM Communication Buffer Status pointer!\n", __FUNCTION__)); - Status = EFI_INVALID_PARAMETER; - goto Exit; - } - Status = MmAllocatePages ( AllocateAnyPages, EfiRuntimeServicesData, From 5da3a949689592d9f3eb1c357a235a2e7fb8ff2b Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 17:24:38 -0800 Subject: [PATCH 20/36] fixing the extra guids --- MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf | 1 - 1 file changed, 1 deletion(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf index 38b32f11..8cf388f0 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf @@ -60,7 +60,6 @@ gEfiPeiMmControlPpiGuid ## CONSUMES gPeiMmSupervisorCommunicationPpiGuid ## PRODUCES gEfiPeiLoadFilePpiGuid ## CONSUMES - gEfiEndOfPeiSignalPpiGuid ## CONSUMES gEfiPeiMmConfigurationPpi ## CONSUMES # MU_CHANGE: Added MM Configuration PPI [Guids] From c456b22bc8adc7d9eee41b382c2a32568f8152b3 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 17:27:43 -0800 Subject: [PATCH 21/36] fixing end of pei --- .../Drivers/MmPeiLaunchers/MmIplPei.c | 16 ++++++++++------ .../Drivers/MmPeiLaunchers/MmIplPei.inf | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index ab5f4b18..a954c2a3 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -76,7 +76,9 @@ SmmCommunicationCommunicate ( ); /** - Event notification that is fired when a GUIDed Event Group is signaled. + This is the callback function on end of PEI. + + This callback is used for call MmEndOfPeiHandler in standalone MM core. @param PeiServices Indirect reference to the PEI Services Table. @param NotifyDescriptor Address of the notification descriptor data structure. @@ -88,7 +90,7 @@ SmmCommunicationCommunicate ( **/ EFI_STATUS EFIAPI -SmmIplGuidedEventNotify ( +EndOfPeiCallback ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi @@ -136,7 +138,7 @@ STATIC EFI_PEI_NOTIFY_DESCRIPTOR mPeiMmIplNotifyList = // (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiEndOfPeiSignalPpiGuid, - SmmIplGuidedEventNotify + EndOfPeiCallback }; // MU_CHANGE: Abstracted function implementation of MmControl->Trigger for PEI @@ -241,7 +243,9 @@ SmmCommunicationCommunicate ( } /** - Event notification that is fired when a GUIDed Event Group is signaled. + This is the callback function on end of PEI. + + This callback is used for call MmEndOfPeiHandler in standalone MM core. @param PeiServices Indirect reference to the PEI Services Table. @param NotifyDescriptor Address of the notification descriptor data structure. @@ -253,7 +257,7 @@ SmmCommunicationCommunicate ( **/ EFI_STATUS EFIAPI -SmmIplGuidedEventNotify ( +EndOfPeiCallback ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi @@ -264,7 +268,7 @@ SmmIplGuidedEventNotify ( } // MU_CHANGE: Abstracted implementation to SmmIplGuidedEventNotifyWork for DXE and PEI - return SmmIplGuidedEventNotifyWorker (NotifyDescriptor->Guid); + return SmmIplGuidedEventNotifyWorker (&gEfiMmEndOfPeiProtocol); } // MU_CHANGE Starts: The MM core address found routine is updated with PEI services diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf index a7746d76..435d77aa 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf @@ -72,6 +72,7 @@ gEfiPeiLoadFilePpiGuid ## CONSUMES gEfiEndOfPeiSignalPpiGuid ## CONSUMES gEfiPeiMmConfigurationPpi ## CONSUMES # MU_CHANGE: Added MM Configuration PPI + gEfiMmEndOfPeiProtocol [Guids] # gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported From 7bc1b57e917c1147e1bfe1db24ad33a7e59c3349 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 17:31:47 -0800 Subject: [PATCH 22/36] Ring 3 broker register the callback --- .../MmSupervisorRing3Broker.c | 41 +++++++++++++++++++ .../MmSupervisorRing3Broker.h | 9 ++++ .../MmSupervisorRing3Broker.inf | 1 + 3 files changed, 51 insertions(+) diff --git a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.c b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.c index 6677e86f..c732eacb 100644 --- a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.c +++ b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.c @@ -30,6 +30,7 @@ // MM_SHIM_MMI_HANDLERS mMmShimMmiHandlers[] = { { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE }, + { MmEndOfPeiHandler, &gEfiMmEndOfPeiProtocol, NULL, FALSE }, { MmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE }, { MmExitBootServiceHandler, &gEfiEventExitBootServicesGuid, NULL, FALSE }, { MmReadyToBootHandler, &gEfiEventReadyToBootGuid, NULL, FALSE }, @@ -242,6 +243,46 @@ MmReadyToLockHandler ( return Status; } +/** + Software MMI handler that is called when the EndOfPei event is signaled. + This function installs the MM EndOfPei Protocol so MM Drivers are informed that + EndOfPei event is signaled. + + @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister(). + @param Context Points to an optional handler context which was specified when the handler was registered. + @param CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-MM environment into an MM environment. + @param CommBufferSize The size of the CommBuffer. + + @return Status Code + +**/ +EFI_STATUS +EFIAPI +MmEndOfPeiHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_HANDLE MmHandle; + + DEBUG ((DEBUG_INFO, "MmEndOfPeiHandler\n")); + // + // Install MM EndOfDxe protocol + // + MmHandle = NULL; + Status = MmInstallUserProtocolInterface ( + &MmHandle, + &gEfiMmEndOfPeiProtocol, + EFI_NATIVE_INTERFACE, + NULL + ); + return Status; +} + /** Software MMI handler that is called when the EndOfDxe event is signaled. This function installs the MM EndOfDxe Protocol so MM Drivers are informed that diff --git a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.h b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.h index c8c8e791..1e8a7d65 100644 --- a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.h +++ b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.h @@ -287,6 +287,15 @@ MmReadyToLockHandler ( IN OUT UINTN *CommBufferSize OPTIONAL ); +EFI_STATUS +EFIAPI +MmEndOfPeiHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ); + EFI_STATUS EFIAPI MmEndOfDxeHandler ( diff --git a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.inf b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.inf index 7e975337..ab9efa25 100644 --- a/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.inf +++ b/MmSupervisorPkg/Drivers/MmSupervisorRing3Broker/MmSupervisorRing3Broker.inf @@ -64,6 +64,7 @@ gEfiDxeMmReadyToLockProtocolGuid # PRODUCES gEfiMmReadyToLockProtocolGuid # PRODUCES gEfiMmEndOfDxeProtocolGuid # PRODUCES + gEfiMmEndOfPeiProtocol # PRODUCES [Guids] gEfiEndOfDxeEventGroupGuid # PRODUCES From a7859abdacadd636bd3caa444a1e7b5d0e6dea16 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 17:35:04 -0800 Subject: [PATCH 23/36] Do the translation --- .../Drivers/MmPeiLaunchers/MmIplPei.c | 122 +++--------------- .../Drivers/MmPeiLaunchers/MmIplPei.inf | 1 + 2 files changed, 19 insertions(+), 104 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index dba181b1..a646467d 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -77,31 +77,10 @@ SmmCommunicationCommunicate ( IN OUT UINTN *CommSize ); -// MU_CHANGE: MM_SUPV: Supervisor communication function prototype - /** - Communicates with a registered handler. - - This function provides a service to send and receive messages from a registered UEFI service. - - @param[in] This The MM_SUPERVISOR_COMMUNICATION_PPI instance. - @param[in] CommBuffer A pointer to the buffer to convey into SMRAM. - @param[in] CommSize The size of the data buffer being passed in.On exit, the size of data - being returned. Zero if the handler does not wish to reply with any data. - - @retval EFI_SUCCESS The message was successfully posted. - @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. -**/ -EFI_STATUS -EFIAPI -SupvCommunicationCommunicate ( - IN CONST MM_SUPERVISOR_COMMUNICATION_PPI *This, - IN OUT VOID *CommBuffer, - IN OUT UINTN *CommSize OPTIONAL - ); + This is the callback function on end of PEI. -/** - Event notification that is fired when a GUIDed Event Group is signaled. + This callback is used for call MmEndOfPeiHandler in standalone MM core. @param PeiServices Indirect reference to the PEI Services Table. @param NotifyDescriptor Address of the notification descriptor data structure. @@ -113,7 +92,7 @@ SupvCommunicationCommunicate ( **/ EFI_STATUS EFIAPI -SmmIplGuidedEventNotify ( +EndOfPeiCallback ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi @@ -176,7 +155,7 @@ STATIC EFI_PEI_NOTIFY_DESCRIPTOR mPeiMmIplNotifyList = // (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiEndOfPeiSignalPpiGuid, - SmmIplGuidedEventNotify + EndOfPeiCallback }; // MU_CHANGE: Abstracted function implementation of MmControl->Trigger for PEI @@ -329,7 +308,9 @@ SmmCommunicationCommunicate ( } /** - Event notification that is fired when a GUIDed Event Group is signaled. + This is the callback function on end of PEI. + + This callback is used for call MmEndOfPeiHandler in standalone MM core. @param PeiServices Indirect reference to the PEI Services Table. @param NotifyDescriptor Address of the notification descriptor data structure. @@ -341,7 +322,7 @@ SmmCommunicationCommunicate ( **/ EFI_STATUS EFIAPI -SmmIplGuidedEventNotify ( +EndOfPeiCallback ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi @@ -352,7 +333,7 @@ SmmIplGuidedEventNotify ( } // MU_CHANGE: Abstracted implementation to SmmIplGuidedEventNotifyWork for DXE and PEI - return SmmIplGuidedEventNotifyWorker (NotifyDescriptor->Guid); + return SmmIplGuidedEventNotifyWorker (&gEfiMmEndOfPeiProtocol); } // MU_CHANGE Starts: MM_SUPV: Will immediately signal MM core to dispatch MM drivers @@ -1094,20 +1075,14 @@ MmIplPeiEntry ( IN CONST EFI_PEI_SERVICES **PeiServices ) { - EFI_STATUS Status; - UINTN Index; - UINT64 MaxSize; - UINTN Size; - UINTN MmramRangeCount; - // UINT64 MmCodeSize; - // EFI_CPU_ARCH_PROTOCOL *CpuArch; - // EFI_STATUS SetAttrStatus; - // EFI_MMRAM_DESCRIPTOR *MmramRangeSmmDriver; - // EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; - EFI_MMRAM_DESCRIPTOR *MmramRanges; - // MU_CHANGE: MM_SUPV: Test supervisor communication before publishing protocol - MM_SUPERVISOR_VERSION_INFO_BUFFER VersionInfo; - MTRR_MEMORY_CACHE_TYPE CacheAttribute; + EFI_STATUS Status; + UINTN Index; + UINT64 MaxSize; + UINTN Size; + UINTN MmramRangeCount; + EFI_MMRAM_DESCRIPTOR *MmramRanges; + MTRR_MEMORY_CACHE_TYPE CacheAttribute; + EFI_MEMORY_DESCRIPTOR CommunicationRegion; Status = PeiServicesRegisterForShadow (FileHandle); @@ -1117,7 +1092,7 @@ MmIplPeiEntry ( // MU_CHANGE: MM_SUPV: Initialize Comm buffer from HOBs first Status = InitializeCommunicationBufferFromHob ( - &mMmSupvCommunication.CommunicationRegion + &CommunicationRegion ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "%a Failed to initialize communication buffer from HOBs - %r\n", __func__, Status)); @@ -1271,67 +1246,6 @@ MmIplPeiEntry ( DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM region to load SMM Core\n")); } - // - // Close all SMRAM ranges - // - // MU_CHANGE: Iterate through each MMRAM for PPI instance - for (Index = 0; Index < MmramRangeCount; Index++) { - Status = mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "SMM IPL failed to close SMRAM windows index %d - %r\n", Index, Status)); - ASSERT (FALSE); - return Status; - } - - // - // Print debug message that the SMRAM window is now closed. - // - DEBUG ((DEBUG_INFO, "MM IPL closed SMRAM window index %d\n", Index)); - } - - // MU_CHANGE: MM_SUPV: Locked immediately after closing instead of waiting for ready to lock event - // - // Lock the SMRAM (Note: Locking SMRAM may not be supported on all platforms) - // - for (Index = 0; Index < MmramRangeCount; Index++) { - Status = mSmmAccess->Lock ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); - if (EFI_ERROR (Status)) { - // - // Print error message that the SMRAM failed to lock... - // - DEBUG ((DEBUG_ERROR, "MM IPL could not lock MMRAM (Index %d) after executing MM Core %r\n", Index, Status)); - ASSERT (FALSE); - return Status; - } - - // - // Print debug message that the SMRAM window is now closed. - // - DEBUG ((DEBUG_INFO, "MM IPL locked SMRAM window index %d\n", Index)); - } - - SECURITY_LOCK_REPORT_EVENT ("Lock MMRAM", HARDWARE_LOCK); // MSCHANGE - - // - // Print debug message that the SMRAM window is now locked. - // - DEBUG ((DEBUG_INFO, "SMM IPL locked SMRAM window\n")); - - // MU_CHANGE: MM_SUPV: We are just making sure this communication to supervisor does not fail after setup. - Status = QuerySupervisorVersion (&VersionInfo); - if (EFI_ERROR (Status)) { - return Status; - } - - // MU_CHANGE: MM_SUPV: Added a forced trigger to load all drivers in MM - // - // Trigger to dispatch MM drivers from inside MM - // - if (!EFI_ERROR (Status)) { - Status = MmDriverDispatchNotify (); - DEBUG ((DEBUG_INFO, "MM driver dispatching returned - %r\n", Status)); - } - // // If the SMM Core could not be loaded then close SMRAM window, free allocated // resources, and return an error so SMM IPL will be unloaded. diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf index a7746d76..435d77aa 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf @@ -72,6 +72,7 @@ gEfiPeiLoadFilePpiGuid ## CONSUMES gEfiEndOfPeiSignalPpiGuid ## CONSUMES gEfiPeiMmConfigurationPpi ## CONSUMES # MU_CHANGE: Added MM Configuration PPI + gEfiMmEndOfPeiProtocol [Guids] # gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported From de21036dfd9dfad9cb362607bd3ec5bf029c74a3 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 17:37:38 -0800 Subject: [PATCH 24/36] revert some changes --- .../Drivers/MmPeiLaunchers/MmIplPei.c | 105 ++++++++++++++++-- 1 file changed, 96 insertions(+), 9 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index a646467d..b30d727e 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -77,6 +77,26 @@ SmmCommunicationCommunicate ( IN OUT UINTN *CommSize ); + // MU_CHANGE: MM_SUPV: Supervisor communication function prototype + +/** + Communicates with a registered handler. + This function provides a service to send and receive messages from a registered UEFI service. + @param[in] This The MM_SUPERVISOR_COMMUNICATION_PPI instance. + @param[in] CommBuffer A pointer to the buffer to convey into SMRAM. + @param[in] CommSize The size of the data buffer being passed in.On exit, the size of data + being returned. Zero if the handler does not wish to reply with any data. + @retval EFI_SUCCESS The message was successfully posted. + @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. +**/ +EFI_STATUS +EFIAPI +SupvCommunicationCommunicate ( + IN CONST MM_SUPERVISOR_COMMUNICATION_PPI *This, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize OPTIONAL + ); + /** This is the callback function on end of PEI. @@ -1075,14 +1095,20 @@ MmIplPeiEntry ( IN CONST EFI_PEI_SERVICES **PeiServices ) { - EFI_STATUS Status; - UINTN Index; - UINT64 MaxSize; - UINTN Size; - UINTN MmramRangeCount; - EFI_MMRAM_DESCRIPTOR *MmramRanges; - MTRR_MEMORY_CACHE_TYPE CacheAttribute; - EFI_MEMORY_DESCRIPTOR CommunicationRegion; + EFI_STATUS Status; + UINTN Index; + UINT64 MaxSize; + UINTN Size; + UINTN MmramRangeCount; + // UINT64 MmCodeSize; + // EFI_CPU_ARCH_PROTOCOL *CpuArch; + // EFI_STATUS SetAttrStatus; + // EFI_MMRAM_DESCRIPTOR *MmramRangeSmmDriver; + // EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; + EFI_MMRAM_DESCRIPTOR *MmramRanges; + // MU_CHANGE: MM_SUPV: Test supervisor communication before publishing protocol + MM_SUPERVISOR_VERSION_INFO_BUFFER VersionInfo; + MTRR_MEMORY_CACHE_TYPE CacheAttribute; Status = PeiServicesRegisterForShadow (FileHandle); @@ -1092,7 +1118,7 @@ MmIplPeiEntry ( // MU_CHANGE: MM_SUPV: Initialize Comm buffer from HOBs first Status = InitializeCommunicationBufferFromHob ( - &CommunicationRegion + &mMmSupvCommunication.CommunicationRegion ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "%a Failed to initialize communication buffer from HOBs - %r\n", __func__, Status)); @@ -1246,6 +1272,67 @@ MmIplPeiEntry ( DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM region to load SMM Core\n")); } + // + // Close all SMRAM ranges + // + // MU_CHANGE: Iterate through each MMRAM for PPI instance + for (Index = 0; Index < MmramRangeCount; Index++) { + Status = mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SMM IPL failed to close SMRAM windows index %d - %r\n", Index, Status)); + ASSERT (FALSE); + return Status; + } + + // + // Print debug message that the SMRAM window is now closed. + // + DEBUG ((DEBUG_INFO, "MM IPL closed SMRAM window index %d\n", Index)); + } + + // MU_CHANGE: MM_SUPV: Locked immediately after closing instead of waiting for ready to lock event + // + // Lock the SMRAM (Note: Locking SMRAM may not be supported on all platforms) + // + for (Index = 0; Index < MmramRangeCount; Index++) { + Status = mSmmAccess->Lock ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); + if (EFI_ERROR (Status)) { + // + // Print error message that the SMRAM failed to lock... + // + DEBUG ((DEBUG_ERROR, "MM IPL could not lock MMRAM (Index %d) after executing MM Core %r\n", Index, Status)); + ASSERT (FALSE); + return Status; + } + + // + // Print debug message that the SMRAM window is now closed. + // + DEBUG ((DEBUG_INFO, "MM IPL locked SMRAM window index %d\n", Index)); + } + + SECURITY_LOCK_REPORT_EVENT ("Lock MMRAM", HARDWARE_LOCK); // MSCHANGE + + // + // Print debug message that the SMRAM window is now locked. + // + DEBUG ((DEBUG_INFO, "SMM IPL locked SMRAM window\n")); + + // MU_CHANGE: MM_SUPV: We are just making sure this communication to supervisor does not fail after setup. + Status = QuerySupervisorVersion (&VersionInfo); + if (EFI_ERROR (Status)) { + return Status; + } + + // MU_CHANGE: MM_SUPV: Added a forced trigger to load all drivers in MM + // + // Trigger to dispatch MM drivers from inside MM + // + if (!EFI_ERROR (Status)) { + Status = MmDriverDispatchNotify (); + DEBUG ((DEBUG_INFO, "MM driver dispatching returned - %r\n", Status)); + } + // // If the SMM Core could not be loaded then close SMRAM window, free allocated // resources, and return an error so SMM IPL will be unloaded. From 4fd35d0da1eebc1f61f41c776c72e2fb31665b0d Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 17:42:53 -0800 Subject: [PATCH 25/36] add back spaces --- MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index b30d727e..95a66e2f 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -77,15 +77,18 @@ SmmCommunicationCommunicate ( IN OUT UINTN *CommSize ); - // MU_CHANGE: MM_SUPV: Supervisor communication function prototype +// MU_CHANGE: MM_SUPV: Supervisor communication function prototype /** Communicates with a registered handler. + This function provides a service to send and receive messages from a registered UEFI service. + @param[in] This The MM_SUPERVISOR_COMMUNICATION_PPI instance. @param[in] CommBuffer A pointer to the buffer to convey into SMRAM. @param[in] CommSize The size of the data buffer being passed in.On exit, the size of data being returned. Zero if the handler does not wish to reply with any data. + @retval EFI_SUCCESS The message was successfully posted. @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. **/ From 205c5c56fb73033c6735650420cf5cf9d9c1336d Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 18:00:46 -0800 Subject: [PATCH 26/36] protocol --- MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf index 435d77aa..aa2b6299 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf @@ -72,7 +72,9 @@ gEfiPeiLoadFilePpiGuid ## CONSUMES gEfiEndOfPeiSignalPpiGuid ## CONSUMES gEfiPeiMmConfigurationPpi ## CONSUMES # MU_CHANGE: Added MM Configuration PPI - gEfiMmEndOfPeiProtocol + +[Protocols] + gEfiMmEndOfPeiProtocol ## PRODUCES [Guids] # gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported From c47f43ee8653d193324abb46f44aba8ea961b6e3 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 1 Dec 2025 19:19:24 -0800 Subject: [PATCH 27/36] fix build --- MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf | 1 - 1 file changed, 1 deletion(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf index fe0dd7a6..aa2b6299 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf @@ -72,7 +72,6 @@ gEfiPeiLoadFilePpiGuid ## CONSUMES gEfiEndOfPeiSignalPpiGuid ## CONSUMES gEfiPeiMmConfigurationPpi ## CONSUMES # MU_CHANGE: Added MM Configuration PPI - gEfiMmEndOfPeiProtocol [Protocols] gEfiMmEndOfPeiProtocol ## PRODUCES From 26544bf336a3f7d30ed5ded3d8cabda363af1592 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 8 Dec 2025 11:52:22 -0800 Subject: [PATCH 28/36] move the mm close and lock back to IPL --- .../Drivers/MmPeiLaunchers/MmIplPei.c | 49 ++++++- .../Drivers/MmPeiLaunchers/MmPeiSupport.c | 133 +----------------- 2 files changed, 47 insertions(+), 135 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index f4ad2d10..30a0a3f7 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -20,8 +20,6 @@ #include #include #include -#include -#include // MU_CHANGE: MM_SUPV: Added MM Supervisor request data structure #include #include @@ -80,9 +78,6 @@ SmmCommunicationCommunicate ( This callback is used for call MmEndOfPeiHandler in standalone MM core. - This callback is used for call MmEndOfPeiHandler in standalone MM core. - - @param PeiServices Indirect reference to the PEI Services Table. @param NotifyDescriptor Address of the notification descriptor data structure. @param Ppi Address of the PPI that was installed. @@ -1033,6 +1028,50 @@ MmIplPeiEntry ( DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM region to load SMM Core\n")); } + // + // Close all SMRAM ranges + // + // MU_CHANGE: Iterate through each MMRAM for PPI instance + for (Index = 0; Index < MmramRangeCount; Index++) { + Status = mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SMM IPL failed to close SMRAM windows index %d - %r\n", Index, Status)); + ASSERT (FALSE); + } + + // + // Print debug message that the SMRAM window is now closed. + // + DEBUG ((DEBUG_INFO, "MM IPL closed SMRAM window index %d\n", Index)); + } + + // MU_CHANGE: MM_SUPV: Locked immediately after closing instead of waiting for ready to lock event + // + // Lock the SMRAM (Note: Locking SMRAM may not be supported on all platforms) + // + for (Index = 0; Index < MmramRangeCount; Index++) { + Status = mSmmAccess->Lock ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); + if (EFI_ERROR (Status)) { + // + // Print error message that the SMRAM failed to lock... + // + DEBUG ((DEBUG_ERROR, "MM IPL could not lock MMRAM (Index %d) after executing MM Core %r\n", Index, Status)); + ASSERT (FALSE); + } + + // + // Print debug message that the SMRAM window is now closed. + // + DEBUG ((DEBUG_INFO, "MM IPL locked SMRAM window index %d\n", Index)); + } + + SECURITY_LOCK_REPORT_EVENT ("Lock MMRAM", HARDWARE_LOCK); // MSCHANGE + + // + // Print debug message that the SMRAM window is now locked. + // + DEBUG ((DEBUG_INFO, "SMM IPL locked SMRAM window\n")); + // // If the SMM Core could not be loaded then close SMRAM window, free allocated // resources, and return an error so SMM IPL will be unloaded. diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c index c7a122ff..836a2b29 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c @@ -118,8 +118,6 @@ STATIC EFI_PEI_PPI_DESCRIPTOR mPeiMmIplPpiList[] = // SMM IPL global variables // EFI_PEI_MM_CONTROL_PPI *mSmmControl; -EFI_PEI_MM_ACCESS_PPI *mSmmAccess; -EFI_MMRAM_DESCRIPTOR *mCurrentMmramRange; EFI_PHYSICAL_ADDRESS mMmramCacheBase; UINT64 mMmramCacheSize; @@ -211,9 +209,9 @@ MmDriverDispatchNotify ( mCommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mMmSupvCommonBuffer; // - // Use Guid to initialize EFI_MM_COMMUNICATE_HEADER structure - // Clear the buffer passed into the Software SMI. This buffer will return - // the status of the SMM Core Dispatcher. + // This is actually an empty payload command, but the EFI_MM_COMMUNICATE_HEADER structure + // comes with a payload of at least one byte. So we set the MessageLength to 1 and + // the first byte to 0. // CopyGuid (&(mCommunicateHeader->HeaderGuid), &gMmSupervisorDriverDispatchGuid); mCommunicateHeader->MessageLength = 1; @@ -269,11 +267,7 @@ MmPeiSupportEntry ( ) { EFI_STATUS Status; - UINTN Index; - UINT64 MaxSize; UINTN Size; - UINTN MmramRangeCount; - EFI_MMRAM_DESCRIPTOR *MmramRanges; MM_SUPERVISOR_VERSION_INFO_BUFFER VersionInfo; Status = PeiServicesRegisterForShadow (FileHandle); @@ -291,18 +285,6 @@ MmPeiSupportEntry ( return Status; } - // - // Get SMM Access PPI - // - Status = (*PeiServices)->LocatePpi ( - PeiServices, - &gEfiPeiMmAccessPpiGuid, - 0, - NULL, - (VOID **)&mSmmAccess - ); - ASSERT_EFI_ERROR (Status); - // // Get SMM Control PPI // @@ -315,102 +297,6 @@ MmPeiSupportEntry ( ); ASSERT_EFI_ERROR (Status); - // - // Open all SMRAM ranges - // - // MU_CHANGE Starts: Need to iterate through all MMRAMs to open one at a time for PPI interface - Size = 0; - Status = mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, &Size, NULL); - if (Status != EFI_BUFFER_TOO_SMALL) { - // This is not right... - ASSERT (FALSE); - return EFI_DEVICE_ERROR; - } - - MmramRanges = AllocatePool (Size); - if (MmramRanges == NULL) { - ASSERT (MmramRanges != NULL); - return EFI_OUT_OF_RESOURCES; - } - - Status = mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, &Size, MmramRanges); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "SMM IPL failed to get SMRAM capabilities - %r\n", Status)); - ASSERT (FALSE); - return Status; - } - - MmramRangeCount = Size / sizeof (EFI_MMRAM_DESCRIPTOR); - // MU_CHANGE Ends - - // - // Find the largest SMRAM range between 1MB and 4GB that is at least 256KB - 4K in size - // - mCurrentMmramRange = NULL; - for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; (UINT64)Index < MmramRangeCount; Index++) { - // - // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization - // - if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { - continue; - } - - if (MmramRanges[Index].CpuStart >= BASE_1MB) { - if ((MmramRanges[Index].CpuStart + MmramRanges[Index].PhysicalSize - 1) <= MAX_ADDRESS) { - if (MmramRanges[Index].PhysicalSize >= MaxSize) { - MaxSize = MmramRanges[Index].PhysicalSize; - mCurrentMmramRange = &MmramRanges[Index]; - } - } - } - } - - // - // Close all SMRAM ranges - // - // MU_CHANGE: Iterate through each MMRAM for PPI instance - for (Index = 0; Index < MmramRangeCount; Index++) { - Status = mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "SMM IPL failed to close SMRAM windows index %d - %r\n", Index, Status)); - ASSERT (FALSE); - return Status; - } - - // - // Print debug message that the SMRAM window is now closed. - // - DEBUG ((DEBUG_INFO, "MM IPL closed SMRAM window index %d\n", Index)); - } - - // MU_CHANGE: MM_SUPV: Locked immediately after closing instead of waiting for ready to lock event - // - // Lock the SMRAM (Note: Locking SMRAM may not be supported on all platforms) - // - for (Index = 0; Index < MmramRangeCount; Index++) { - Status = mSmmAccess->Lock ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); - if (EFI_ERROR (Status)) { - // - // Print error message that the SMRAM failed to lock... - // - DEBUG ((DEBUG_ERROR, "MM IPL could not lock MMRAM (Index %d) after executing MM Core %r\n", Index, Status)); - ASSERT (FALSE); - return Status; - } - - // - // Print debug message that the SMRAM window is now closed. - // - DEBUG ((DEBUG_INFO, "MM IPL locked SMRAM window index %d\n", Index)); - } - - SECURITY_LOCK_REPORT_EVENT ("Lock MMRAM", HARDWARE_LOCK); // MSCHANGE - - // - // Print debug message that the SMRAM window is now locked. - // - DEBUG ((DEBUG_INFO, "SMM IPL locked SMRAM window\n")); - // MU_CHANGE: MM_SUPV: We are just making sure this communication to supervisor does not fail after setup. Status = QuerySupervisorVersion (&VersionInfo); if (EFI_ERROR (Status)) { @@ -426,19 +312,6 @@ MmPeiSupportEntry ( DEBUG ((DEBUG_INFO, "MM driver dispatching returned - %r\n", Status)); } - // - // If the SMM Core could not be loaded then close SMRAM window, free allocated - // resources, and return an error so SMM IPL will be unloaded. - // - if ((mCurrentMmramRange == NULL) || EFI_ERROR (Status)) { - // - // Free all allocated resources - // - FreePool ((VOID *)MmramRanges); - - return EFI_UNSUPPORTED; - } - // // Install MM Communication and Supervisor MM Communication PPI // From 2537813b50a6fd31efb9bb423f42b87fe9564749 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 8 Dec 2025 12:38:58 -0800 Subject: [PATCH 29/36] fixing the build --- .../Drivers/MmPeiLaunchers/MmIplPei.c | 46 +------------------ .../Drivers/MmPeiLaunchers/MmPeiSupport.c | 1 - 2 files changed, 2 insertions(+), 45 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index 30a0a3f7..a954c2a3 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include // MU_CHANGE: MM_SUPV: Added MM Supervisor request data structure #include #include @@ -1028,50 +1030,6 @@ MmIplPeiEntry ( DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM region to load SMM Core\n")); } - // - // Close all SMRAM ranges - // - // MU_CHANGE: Iterate through each MMRAM for PPI instance - for (Index = 0; Index < MmramRangeCount; Index++) { - Status = mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "SMM IPL failed to close SMRAM windows index %d - %r\n", Index, Status)); - ASSERT (FALSE); - } - - // - // Print debug message that the SMRAM window is now closed. - // - DEBUG ((DEBUG_INFO, "MM IPL closed SMRAM window index %d\n", Index)); - } - - // MU_CHANGE: MM_SUPV: Locked immediately after closing instead of waiting for ready to lock event - // - // Lock the SMRAM (Note: Locking SMRAM may not be supported on all platforms) - // - for (Index = 0; Index < MmramRangeCount; Index++) { - Status = mSmmAccess->Lock ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index); - if (EFI_ERROR (Status)) { - // - // Print error message that the SMRAM failed to lock... - // - DEBUG ((DEBUG_ERROR, "MM IPL could not lock MMRAM (Index %d) after executing MM Core %r\n", Index, Status)); - ASSERT (FALSE); - } - - // - // Print debug message that the SMRAM window is now closed. - // - DEBUG ((DEBUG_INFO, "MM IPL locked SMRAM window index %d\n", Index)); - } - - SECURITY_LOCK_REPORT_EVENT ("Lock MMRAM", HARDWARE_LOCK); // MSCHANGE - - // - // Print debug message that the SMRAM window is now locked. - // - DEBUG ((DEBUG_INFO, "SMM IPL locked SMRAM window\n")); - // // If the SMM Core could not be loaded then close SMRAM window, free allocated // resources, and return an error so SMM IPL will be unloaded. diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c index 836a2b29..5bab5d75 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c @@ -267,7 +267,6 @@ MmPeiSupportEntry ( ) { EFI_STATUS Status; - UINTN Size; MM_SUPERVISOR_VERSION_INFO_BUFFER VersionInfo; Status = PeiServicesRegisterForShadow (FileHandle); From e50c34e1f297367d6821a8e8f7606a9c5eae2c67 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 8 Dec 2025 13:27:39 -0800 Subject: [PATCH 30/36] clean up the inf --- .../Drivers/MmPeiLaunchers/MmIplPei.c | 39 ++++++++++++------- .../Drivers/MmPeiLaunchers/MmIplPei.inf | 5 +-- .../Drivers/MmPeiLaunchers/MmPeiSupport.inf | 30 ++------------ 3 files changed, 29 insertions(+), 45 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index a954c2a3..3c3507ee 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -277,7 +277,8 @@ EndOfPeiCallback ( Searches MmCore in all published firmware Volumes and loads the first instance that contains MmCore. - @param[in] Buffer Placeholder for address of MM core located by this routine. + @param[out] Buffer Placeholder for address of MM core located by this routine. + @param[out] MmCoreFileName Placeholder for the GUID of the MM core file located by this routine. @retval EFI_SUCCESS This function located MM core successfully. @retval Others Errors returned by PeiServices routines. @@ -285,7 +286,8 @@ EndOfPeiCallback ( **/ EFI_STATUS MmIplPeiFindMmCore ( - OUT VOID **Buffer + OUT VOID **Buffer, + OUT EFI_GUID *MmCoreFileName ) { EFI_STATUS Status; @@ -293,6 +295,10 @@ MmIplPeiFindMmCore ( EFI_PEI_FV_HANDLE VolumeHandle; EFI_PEI_FILE_HANDLE FileHandle; + if (Buffer == NULL || MmCoreFileName == NULL) { + return EFI_INVALID_PARAMETER; + } + Instance = 0; while (TRUE) { // @@ -315,17 +321,21 @@ MmIplPeiFindMmCore ( FileHandle = NULL; Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_MM_CORE_STANDALONE, VolumeHandle, &FileHandle); if (!EFI_ERROR (Status)) { - // - // Find MmCore FileHandle in this volume, then we skip other firmware volume and - // return the FileHandle. Search Section now. - // - Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, Buffer); - if (EFI_ERROR (Status)) { - break; - } + ASSERT (FileHandle != NULL); + if (FileHandle != NULL) { + CopyGuid (MmCoreFileName, &((EFI_FFS_FILE_HEADER *)FileHandle)->Name); + DEBUG ((DEBUG_INFO, "Mm core has file name as %g\n", MmCoreFileName)); + // + // Find MmCore FileHandle in this volume, then we skip other firmware volume and + // return the FileHandle. Search Section now. + // + Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, Buffer); + if (EFI_ERROR (Status)) { + break; + } - return EFI_SUCCESS; - break; + return EFI_SUCCESS; + } } // @@ -491,6 +501,7 @@ ExecuteMmCoreFromMmram ( UINTN PageCount; STANDALONE_MM_FOUNDATION_ENTRY_POINT EntryPoint; VOID *HobStart; + EFI_GUID MmCoreFileName; DEBUG ((DEBUG_INFO, "%a Enters...\n", __func__)); // @@ -498,7 +509,7 @@ ExecuteMmCoreFromMmram ( // SourceBuffer = NULL; // MU_CHANGE: The MM core address found routine is updated with PEI services - Status = MmIplPeiFindMmCore (&SourceBuffer); + Status = MmIplPeiFindMmCore (&SourceBuffer, &MmCoreFileName); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a Failed to find MM core file - %r...\n", __func__, Status)); goto Exit; @@ -572,7 +583,7 @@ ExecuteMmCoreFromMmram ( EntryPoint = (STANDALONE_MM_FOUNDATION_ENTRY_POINT)(UINTN)ImageContext.EntryPoint; BuildModuleHob ( - &gMmSupervisorCoreGuid, + &MmCoreFileName, ImageContext.ImageAddress, (UINT64)EFI_PAGES_TO_SIZE (PageCount), (EFI_PHYSICAL_ADDRESS)(UINTN)ImageContext.EntryPoint diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf index aa2b6299..11b70c17 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf @@ -68,7 +68,6 @@ gEfiPeiSmmCommunicationPpiGuid ## PRODUCES gEfiPeiMmAccessPpiGuid ## CONSUMES gEfiPeiMmControlPpiGuid ## CONSUMES - gPeiMmSupervisorCommunicationPpiGuid ## PRODUCES gEfiPeiLoadFilePpiGuid ## CONSUMES gEfiEndOfPeiSignalPpiGuid ## CONSUMES gEfiPeiMmConfigurationPpi ## CONSUMES # MU_CHANGE: Added MM Configuration PPI @@ -79,13 +78,11 @@ [Guids] # gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported gMmCoreMmProfileGuid ## SOMETIMES_CONSUMES - gMmCommonRegionHobGuid ## PRODUCES - gMmSupervisorDriverDispatchGuid ## PRODUCES ## Invoke driver dispatcher + gMmCommonRegionHobGuid ## CONSUMES gMmSupervisorRequestHandlerGuid ## CONSUMES gEfiMmPeiMmramMemoryReserveGuid ## CONSUMES gEfiSmmSmramMemoryGuid ## CONSUMES gMmCommBufferHobGuid ## CONSUMES - gMmSupervisorCoreGuid ## CONSUMES [Pcd] # gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf index 8cf388f0..a2297c2b 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf @@ -1,5 +1,5 @@ ## @file -# This module provide an MM CIS compliant implementation of MM IPL in PEI. +# This module provides the MM supervisor communication PPI service. # # Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
# Copyright (c) Microsoft Corporation. @@ -40,48 +40,24 @@ BaseLib BaseMemoryLib PeCoffLib - CacheMaintenanceLib MemoryAllocationLib DebugLib PcdLib ReportStatusCodeLib - SafeIntLib #MU_CHANGE: BZ3398 - SecurityLockAuditLib #MSCHANGE - PeCoffGetEntryPointLib - MtrrLib #MU_CHANGE: MM_SUPV: MMRAM region cachability during init - PerformanceLib #MU_CHANGE: MM_SUPV: Added performance data points PeiServicesLib #MU_CHANGE: Add PeiServicesLib to INF HobLib #MU_CHANGE: Add HobLib to INF PanicLib #MU_CHANGE: Add PanicLib to INF [Ppis] - gEfiPeiSmmCommunicationPpiGuid ## PRODUCES - gEfiPeiMmAccessPpiGuid ## CONSUMES gEfiPeiMmControlPpiGuid ## CONSUMES gPeiMmSupervisorCommunicationPpiGuid ## PRODUCES - gEfiPeiLoadFilePpiGuid ## CONSUMES - gEfiPeiMmConfigurationPpi ## CONSUMES # MU_CHANGE: Added MM Configuration PPI [Guids] - # gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported - gMmCoreMmProfileGuid ## SOMETIMES_CONSUMES - gMmCommonRegionHobGuid ## PRODUCES + gMmCommonRegionHobGuid ## CONSUMES gMmSupervisorDriverDispatchGuid ## PRODUCES ## Invoke driver dispatcher gMmSupervisorRequestHandlerGuid ## CONSUMES - gEfiMmPeiMmramMemoryReserveGuid ## CONSUMES - gEfiSmmSmramMemoryGuid ## CONSUMES gMmCommBufferHobGuid ## CONSUMES gMmSupervisorCoreGuid ## CONSUMES -[Pcd] - # gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber ## SOMETIMES_CONSUMES ## MU_CHANGE: Feature unsupported - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES - gMmSupervisorPkgTokenSpaceGuid.PcdMmIplX64RelayFile ## CONSUMES - gMmSupervisorPkgTokenSpaceGuid.PcdPeiMmInitLongModeStackSize ## CONSUMES - [Depex] - gEfiPeiMmAccessPpiGuid AND gEfiPeiMmControlPpiGuid AND gMmCommunicationBufferReadyPpiGuid + gEfiPeiSmmCommunicationPpiGuid From b66f8d3beb387ef0dcd0feaebf02e333b05a5578 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 8 Dec 2025 13:44:25 -0800 Subject: [PATCH 31/36] fixing dsc --- MmSupervisorPkg/MmSupervisorPkg.dsc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MmSupervisorPkg/MmSupervisorPkg.dsc b/MmSupervisorPkg/MmSupervisorPkg.dsc index 89c729c6..5affbcb2 100644 --- a/MmSupervisorPkg/MmSupervisorPkg.dsc +++ b/MmSupervisorPkg/MmSupervisorPkg.dsc @@ -128,9 +128,9 @@ [Components] MmSupervisorPkg/Library/BaseMmSupervisorCoreInitLibNull/BaseMmSupervisorCoreInitLibNull.inf MmSupervisorPkg/Library/DxeMmSupervisorVersionPublicationLib/DxeMmSupervisorVersionPublicationLib.inf - -[Components.IA32] MmSupervisorPkg/Library/MmSupervisorUnblockMemoryLib/MmSupervisorUnblockMemoryLibPei.inf + + MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.inf MmSupervisorPkg/Drivers/MmCommunicationBuffer/MmCommunicationBufferPei.inf MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.inf From 74c08165a36d7ecf2dbe2351fdb96bd11d6934dd Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 8 Dec 2025 13:46:26 -0800 Subject: [PATCH 32/36] uncru --- MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c | 6 +++--- MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c index 3c3507ee..2c369383 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmIplPei.c @@ -286,8 +286,8 @@ EndOfPeiCallback ( **/ EFI_STATUS MmIplPeiFindMmCore ( - OUT VOID **Buffer, - OUT EFI_GUID *MmCoreFileName + OUT VOID **Buffer, + OUT EFI_GUID *MmCoreFileName ) { EFI_STATUS Status; @@ -295,7 +295,7 @@ MmIplPeiFindMmCore ( EFI_PEI_FV_HANDLE VolumeHandle; EFI_PEI_FILE_HANDLE FileHandle; - if (Buffer == NULL || MmCoreFileName == NULL) { + if ((Buffer == NULL) || (MmCoreFileName == NULL)) { return EFI_INVALID_PARAMETER; } diff --git a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c index 5bab5d75..13507624 100644 --- a/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c +++ b/MmSupervisorPkg/Drivers/MmPeiLaunchers/MmPeiSupport.c @@ -235,7 +235,7 @@ MmDriverDispatchNotify ( // Get the status returned from the MM Core Dispatcher // if (Size >= sizeof (EFI_STATUS)) { - Status = *(EFI_STATUS*)mCommunicateHeader->Data; + Status = *(EFI_STATUS *)mCommunicateHeader->Data; } else { Status = EFI_DEVICE_ERROR; } @@ -266,7 +266,7 @@ MmPeiSupportEntry ( IN CONST EFI_PEI_SERVICES **PeiServices ) { - EFI_STATUS Status; + EFI_STATUS Status; MM_SUPERVISOR_VERSION_INFO_BUFFER VersionInfo; Status = PeiServicesRegisterForShadow (FileHandle); From 0ceb8a702a5ea27e7e084bf6f21ca3ab53f2e135 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Mon, 8 Dec 2025 14:02:53 -0800 Subject: [PATCH 33/36] adding x64 PEI build --- MmSupervisorPkg/MmSupervisorPkg.dsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MmSupervisorPkg/MmSupervisorPkg.dsc b/MmSupervisorPkg/MmSupervisorPkg.dsc index 5affbcb2..caaf7568 100644 --- a/MmSupervisorPkg/MmSupervisorPkg.dsc +++ b/MmSupervisorPkg/MmSupervisorPkg.dsc @@ -55,7 +55,7 @@ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf MmSupervisorCoreInitLib|MmSupervisorPkg/Library/BaseMmSupervisorCoreInitLibNull/BaseMmSupervisorCoreInitLibNull.inf -[LibraryClasses.IA32] +[LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf From 09f7eed497b5b41b398eec09762b2f822f2bbce8 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Tue, 9 Dec 2025 23:36:48 -0800 Subject: [PATCH 34/36] Supervisor changes to bubble up the user mode not ready case --- MmSupervisorPkg/Core/Handler/Mmi.c | 5 ++ MmSupervisorPkg/Core/MmSupervisorCore.c | 68 ++++++++++++++++++----- MmSupervisorPkg/Core/MmSupervisorCore.h | 24 ++++++++ MmSupervisorPkg/Core/MmSupervisorCore.inf | 1 + 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/MmSupervisorPkg/Core/Handler/Mmi.c b/MmSupervisorPkg/Core/Handler/Mmi.c index 03726031..f291e46e 100644 --- a/MmSupervisorPkg/Core/Handler/Mmi.c +++ b/MmSupervisorPkg/Core/Handler/Mmi.c @@ -212,6 +212,11 @@ MmiManage ( CommBuffer, CommBufferSize ); + if (Status == EFI_NOT_READY) { + // This is from the wrap itself due to ring 3 broker not ready, so we bail the loop and bubble it back to the caller + ReturnStatus = Status; + break; + } } else if (SupervisorPath && MmiHandler->IsSupervisor) { Status = MmiHandler->Handler ( (EFI_HANDLE)MmiHandler, diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.c b/MmSupervisorPkg/Core/MmSupervisorCore.c index 546d7816..3ed15974 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.c +++ b/MmSupervisorPkg/Core/MmSupervisorCore.c @@ -108,10 +108,11 @@ EFI_MEMORY_DESCRIPTOR mMmSupervisorAccessBuffer[MM_OPEN_BUFFER_CNT]; // Table of MMI Handlers that are registered by the MM Core when it is initialized // MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = { - { MmDriverDispatchHandler, &gMmSupervisorDriverDispatchGuid, NULL, TRUE }, - { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE }, - { MmSupvRequestHandler, &gMmSupervisorRequestHandlerGuid, NULL, FALSE }, - { NULL, NULL, NULL, FALSE }, + { MmDriverDispatchHandler, &gEventMmDispatchGuid, NULL, FALSE, FALSE }, + { MmDriverDispatchHandler, &gMmSupervisorDriverDispatchGuid, NULL, TRUE, TRUE }, + { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE, TRUE }, + { MmSupvRequestHandler, &gMmSupervisorRequestHandlerGuid, NULL, FALSE, TRUE }, + { NULL, NULL, NULL, FALSE, TRUE }, }; EFI_SYSTEM_TABLE *mEfiSystemTable; @@ -347,6 +348,32 @@ PrepareCommonBuffers ( return Status; } +/** + Software MMI handler that is called when the gEventMmDispatchGuid event is called + This function is a stub in the user mode that does not do anything but to pass the + invocation of driver dispatcher call from the IPL. + + @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister(). + @param Context Points to an optional handler context which was specified when the handler was registered. + @param CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-MM environment into an MM environment. + @param CommBufferSize The size of the CommBuffer. + + @return Status Code + +**/ +EFI_STATUS +EFIAPI +MmDriverDispatchHandlerNull ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + return EFI_SUCCESS; +} + /** Software MMI handler that should be triggered from non-MM environment upon DxeMmReadyToLock event. This function unregisters the SUPERVISOR MMIs that are not required after Ready To Lock @@ -385,13 +412,18 @@ MmReadyToLockHandler ( // for (Index = 0; mMmCoreMmiHandlers[Index].HandlerType != NULL; Index++) { if (mMmCoreMmiHandlers[Index].UnRegister) { - Status = MmiHandlerSupvUnRegister (mMmCoreMmiHandlers[Index].DispatchHandle); + if (mMmCoreMmiHandlers[Index].SupervisorHandler) { + Status = MmiHandlerSupvUnRegister (mMmCoreMmiHandlers[Index].DispatchHandle); + } else { + Status = MmiHandlerUserUnRegister (mMmCoreMmiHandlers[Index].DispatchHandle); + } if (EFI_ERROR (Status)) { DEBUG (( DEBUG_ERROR, - "Failed to unregister supervisor handler No. %d %g - %r\n", + "Failed to unregister supervisor handler No. %d %g (%a) - %r\n", Index, mMmCoreMmiHandlers[Index].HandlerType, + mMmCoreMmiHandlers[Index].SupervisorHandler ? "S" : "U", Status )); } @@ -547,7 +579,8 @@ MmEntryPoint ( mMmCommunicationBufferStatus.IsCommBufferValid = FALSE; mMmCommunicationBufferStatus.ReturnBufferSize = BufferSize; - mMmCommunicationBufferStatus.ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; + // Rather than typical not_found on errors, this will bubble up the not_ready error. + mMmCommunicationBufferStatus.ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : ((Status == EFI_NOT_READY) ? EFI_NOT_READY : EFI_NOT_FOUND); } else { // // This should be supervisor communicate channel, everything can be ring 0 buffer fine @@ -1156,12 +1189,21 @@ MmSupervisorMain ( // Register all handlers in the core table // for (Index = 0; mMmCoreMmiHandlers[Index].HandlerType != NULL; Index++) { - Status = MmiSupvHandlerRegister ( - mMmCoreMmiHandlers[Index].Handler, - mMmCoreMmiHandlers[Index].HandlerType, - &mMmCoreMmiHandlers[Index].DispatchHandle - ); - DEBUG ((DEBUG_INFO, "MmiHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status)); + if (mMmCoreMmiHandlers[Index].SupervisorHandler) { + Status = MmiSupvHandlerRegister ( + mMmCoreMmiHandlers[Index].Handler, + mMmCoreMmiHandlers[Index].HandlerType, + &mMmCoreMmiHandlers[Index].DispatchHandle + ); + DEBUG ((DEBUG_INFO, "MmiSupvHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status)); + } else { + Status = MmiUserHandlerRegister ( + mMmCoreMmiHandlers[Index].Handler, + mMmCoreMmiHandlers[Index].HandlerType, + &mMmCoreMmiHandlers[Index].DispatchHandle + ); + DEBUG ((DEBUG_INFO, "MmiUserHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status)); + } } Status = InitializeMmSupervisorTestAgents (); diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.h b/MmSupervisorPkg/Core/MmSupervisorCore.h index d18911c8..7fe6e75a 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.h +++ b/MmSupervisorPkg/Core/MmSupervisorCore.h @@ -61,6 +61,7 @@ typedef struct { EFI_GUID *HandlerType; EFI_HANDLE DispatchHandle; BOOLEAN UnRegister; + BOOLEAN SupervisorHandler; } MM_CORE_MMI_HANDLERS; // @@ -779,6 +780,29 @@ MmDriverDispatchHandler ( IN OUT UINTN *CommBufferSize OPTIONAL ); +/** + Software MMI handler that is called when the gEventMmDispatchGuid event is called + This function is a stub in the user mode that does not do anything but to pass the + invocation of driver dispatcher call from the IPL. + + @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister(). + @param Context Points to an optional handler context which was specified when the handler was registered. + @param CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-MM environment into an MM environment. + @param CommBufferSize The size of the CommBuffer. + + @return Status Code + +**/ +EFI_STATUS +EFIAPI +MmDriverDispatchHandlerNull ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL +); + /** This function is the main entry point for an MM handler dispatch or communicate-based callback. diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.inf b/MmSupervisorPkg/Core/MmSupervisorCore.inf index a7923428..02acd267 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.inf +++ b/MmSupervisorPkg/Core/MmSupervisorCore.inf @@ -236,6 +236,7 @@ gMmSupervisorRequestHandlerGuid ## SOMETIMES_CONSUMES ## GUID # SmiHandlerRegister gMmSupervisorPolicyFileGuid ## CONSUMES gMmPagingAuditMmiHandlerGuid ## SOMETIMES_CONSUMES + gEventMmDispatchGuid ## CONSUMES gEfiHobMemoryAllocModuleGuid gEfiMmPeiMmramMemoryReserveGuid From 0ff44ca7412ca321ae1552bfc782773829bee498 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Wed, 10 Dec 2025 10:29:49 -0800 Subject: [PATCH 35/36] simpler? --- MmSupervisorPkg/Core/MmSupervisorCore.c | 33 +++++-------------------- MmSupervisorPkg/Core/MmSupervisorCore.h | 23 ----------------- 2 files changed, 6 insertions(+), 50 deletions(-) diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.c b/MmSupervisorPkg/Core/MmSupervisorCore.c index 3ed15974..66390ad9 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.c +++ b/MmSupervisorPkg/Core/MmSupervisorCore.c @@ -108,7 +108,12 @@ EFI_MEMORY_DESCRIPTOR mMmSupervisorAccessBuffer[MM_OPEN_BUFFER_CNT]; // Table of MMI Handlers that are registered by the MM Core when it is initialized // MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = { - { MmDriverDispatchHandler, &gEventMmDispatchGuid, NULL, FALSE, FALSE }, + // Note: The driver dispatch handler is registered in user handler pool, to suffice the needs + // if a driver dispatch call is invoked from user space. The handler is intentionally left + // to NULL. Because if the ring 3 broker is ready, supervisor will dispatch to this handler + // after demotion, which will trip on #GP due to SMAP. Otherwise, if this is invoked before + // ring 3 broker being dispatched, the demotion routine will directly bail with EFI_NOT_READY. + { NULL, &gEventMmDispatchGuid, NULL, FALSE, FALSE }, { MmDriverDispatchHandler, &gMmSupervisorDriverDispatchGuid, NULL, TRUE, TRUE }, { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE, TRUE }, { MmSupvRequestHandler, &gMmSupervisorRequestHandlerGuid, NULL, FALSE, TRUE }, @@ -348,32 +353,6 @@ PrepareCommonBuffers ( return Status; } -/** - Software MMI handler that is called when the gEventMmDispatchGuid event is called - This function is a stub in the user mode that does not do anything but to pass the - invocation of driver dispatcher call from the IPL. - - @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-MM environment into an MM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -MmDriverDispatchHandlerNull ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context OPTIONAL, - IN OUT VOID *CommBuffer OPTIONAL, - IN OUT UINTN *CommBufferSize OPTIONAL - ) -{ - return EFI_SUCCESS; -} - /** Software MMI handler that should be triggered from non-MM environment upon DxeMmReadyToLock event. This function unregisters the SUPERVISOR MMIs that are not required after Ready To Lock diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.h b/MmSupervisorPkg/Core/MmSupervisorCore.h index 7fe6e75a..5d923cc4 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.h +++ b/MmSupervisorPkg/Core/MmSupervisorCore.h @@ -780,29 +780,6 @@ MmDriverDispatchHandler ( IN OUT UINTN *CommBufferSize OPTIONAL ); -/** - Software MMI handler that is called when the gEventMmDispatchGuid event is called - This function is a stub in the user mode that does not do anything but to pass the - invocation of driver dispatcher call from the IPL. - - @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-MM environment into an MM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -MmDriverDispatchHandlerNull ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context OPTIONAL, - IN OUT VOID *CommBuffer OPTIONAL, - IN OUT UINTN *CommBufferSize OPTIONAL -); - /** This function is the main entry point for an MM handler dispatch or communicate-based callback. From 149d82546a2ae945eb872f76b19aac821d236834 Mon Sep 17 00:00:00 2001 From: Kun Qin Date: Wed, 10 Dec 2025 11:13:37 -0800 Subject: [PATCH 36/36] still need a real handler --- MmSupervisorPkg/Core/MmSupervisorCore.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/MmSupervisorPkg/Core/MmSupervisorCore.c b/MmSupervisorPkg/Core/MmSupervisorCore.c index 66390ad9..e4699fcd 100644 --- a/MmSupervisorPkg/Core/MmSupervisorCore.c +++ b/MmSupervisorPkg/Core/MmSupervisorCore.c @@ -110,14 +110,15 @@ EFI_MEMORY_DESCRIPTOR mMmSupervisorAccessBuffer[MM_OPEN_BUFFER_CNT]; MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = { // Note: The driver dispatch handler is registered in user handler pool, to suffice the needs // if a driver dispatch call is invoked from user space. The handler is intentionally left - // to NULL. Because if the ring 3 broker is ready, supervisor will dispatch to this handler - // after demotion, which will trip on #GP due to SMAP. Otherwise, if this is invoked before - // ring 3 broker being dispatched, the demotion routine will directly bail with EFI_NOT_READY. - { NULL, &gEventMmDispatchGuid, NULL, FALSE, FALSE }, - { MmDriverDispatchHandler, &gMmSupervisorDriverDispatchGuid, NULL, TRUE, TRUE }, - { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE, TRUE }, - { MmSupvRequestHandler, &gMmSupervisorRequestHandlerGuid, NULL, FALSE, TRUE }, - { NULL, NULL, NULL, FALSE, TRUE }, + // to duplicate the real dispatcher. Because if the ring 3 broker is ready, supervisor will + // dispatch to this handler after demotion, which will trip on #GP due to SMAP. Otherwise, + // if this is invoked before ring 3 broker being dispatched, the demotion routine will + // directly bail with EFI_NOT_READY. + { MmDriverDispatchHandler, &gEventMmDispatchGuid, NULL, FALSE, FALSE }, + { MmDriverDispatchHandler, &gMmSupervisorDriverDispatchGuid, NULL, TRUE, TRUE }, + { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE, TRUE }, + { MmSupvRequestHandler, &gMmSupervisorRequestHandlerGuid, NULL, FALSE, TRUE }, + { NULL, NULL, NULL, FALSE, TRUE }, }; EFI_SYSTEM_TABLE *mEfiSystemTable;