|
| 1 | +<!--- @file |
| 2 | + First Chapter of Standalone MM Getting Started Guide |
| 3 | +
|
| 4 | + Copyright (c) 2025, Intel Corporation. All rights reserved.<BR> |
| 5 | +
|
| 6 | + Redistribution and use in source (original document form) and 'compiled' |
| 7 | + forms (converted to PDF, epub, HTML and other formats) with or without |
| 8 | + modification, are permitted provided that the following conditions are met: |
| 9 | +
|
| 10 | + 1) Redistributions of source code (original document form) must retain the |
| 11 | + above copyright notice, this list of conditions and the following |
| 12 | + disclaimer as the first lines of this file unmodified. |
| 13 | +
|
| 14 | + 2) Redistributions in compiled form (transformed to other DTDs, converted to |
| 15 | + PDF, epub, HTML and other formats) must reproduce the above copyright |
| 16 | + notice, this list of conditions and the following disclaimer in the |
| 17 | + documentation and/or other materials provided with the distribution. |
| 18 | +
|
| 19 | + THIS DOCUMENTATION IS PROVIDED BY TIANOCORE PROJECT "AS IS" AND ANY EXPRESS OR |
| 20 | + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 21 | + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
| 22 | + EVENT SHALL TIANOCORE PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 | + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 24 | + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
| 25 | + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 26 | + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| 27 | + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF |
| 28 | + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | +
|
| 30 | +--> |
| 31 | + |
| 32 | +# MM Introduction |
| 33 | + |
| 34 | +## SMM and MM Overview |
| 35 | + |
| 36 | +This section describes the main differences between Traditional SMM and Standalone MM. A detailed comparison of the Traditional MM and Standalone MM load process is described in the PI Specification sections "Initializing Management Mode in MM Traditional Mode" and "Initializing Management Mode in Standalone Mode" respectively. |
| 37 | + |
| 38 | +In the following comparison, we will use "SMM" to represent "Traditional SMM" and "MM" to represent "Standalone MM". |
| 39 | + |
| 40 | +SMM Driver: |
| 41 | + |
| 42 | +- Module type is `DXE_SMM_DRIVER`. The entry point of an SMM driver follows the UEFI specification `EFI_IMAGE_ENTRY_POINT`. |
| 43 | +- SMM driver can access the DXE, UEFI, and SMM services during initialization, but can only access SMM services during runtime. |
| 44 | +- Launches at the DXE phase, because SMM might have dependencies on DXE. |
| 45 | +- Multiple rounds of dispatch depend on the `gEfiEventDxeDispatchGuid` event. |
| 46 | +- Uses PEI HOBs. |
| 47 | +- No memory protection before the end of DXE: `PiSmmCore` installs the `EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE` at the `gEfiEndOfDxeEventGroupGuid` event. |
| 48 | +- Can access non-MMRAM memory types at runtime: `EfiReservedMemoryType`, `EfiRuntimeServicesData`, and `EfiACPIMemoryNVS`. |
| 49 | + |
| 50 | +MM Driver: |
| 51 | + |
| 52 | +- Module type is `MM_STANDALONE`. The entry point of an updatable MM driver follows the PI specification `MM_IMAGE_ENTRY_POINT`. |
| 53 | +- A Standalone MM driver must only refer to MM servers. |
| 54 | +- Launches early in the PEI phase. |
| 55 | +- Two rounds of dispatch depend on the `gEventMmDispatchGuid` event. Refer to section **MM Driver Dispatch** for details. |
| 56 | +- Cannot access any non-MMRAM memory unless the `MmUnblockMemoryRequest()` API is called for the non-MMRAM memory. Refer to section **Non-MMRAM Access** for details. |
| 57 | +- Uses MM self-owned HOBs. Refer to section **MM HOBs** for details. |
| 58 | +- Early memory protection in PEI: `StandaloneMmCore` installs the `EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE` once the second round of dispatch finishes. Refer to section **Memory Protection** for details. |
| 59 | + |
| 60 | +## MM Driver Dispatch |
| 61 | + |
| 62 | +For traditional SMM drivers, they are dispatched within multiple rounds: The dispatch is hooked on the `gEfiEventDxeDispatchGuid` event, which is signaled by DXE Core when DXE Core finishes one round of dispatch. |
| 63 | + |
| 64 | +`StandaloneMmIpl` is a PEIM responsible for locating and loading `StandaloneMmCore`. All the MM drivers are dispatched by `StandaloneMmCore` in the 2-round dispatches in X86: |
| 65 | + |
| 66 | +- **1st round**: `StandaloneMmCore` dispatches MM drivers in its IPL entry point running in non-SMM mode. It exits to `StandaloneMmIpl` after `PiSmmCpuStandaloneMm` installs the SMI handler in its entry point. |
| 67 | +- **2nd round**: `StandaloneMmIpl` triggers SMI (`gEventMmDispatchGuid`) to inform `StandaloneMmCore` to dispatch the remaining MM drivers in SMM mode in its SMI entry point. |
| 68 | + |
| 69 | +The following flow chart describes the MM driver dispatch flow: |
| 70 | + |
| 71 | + |
| 72 | +###### Figure 1: MM Driver Dispatch Flow |
| 73 | + |
| 74 | +## MM Communication Buffer |
| 75 | + |
| 76 | +MM communication buffer is specific memory regions used for communication between the Non-MM and MM environment. |
| 77 | + |
| 78 | +Traditional SMM Communication Buffer can be allocated by each DXE driver. It can be any `EfiReservedMemoryType`, `EfiRuntimeServicesData` or `EfiACPIMemoryNVS` runtime buffer. SMI Handlers directly access them. There is no protection of access/call out before `EndOfDxe`. |
| 79 | + |
| 80 | +Standalone MM introduces a more secure method for handling MM Communication Buffer. `StandaloneMmIpl` is responsible for allocating and unblocking a fixed size of runtime memory (non-MMRAM) for `CommBuffer` (`MdeModulePkg/Include/Guid/MmCommBuffer.h`) between non-MM and MM. `StandaloneMmCore` allocates a shadowed communication buffer in MMRAM accordingly. The `CommBuffer` will be used by the MM Communication PPI and Protocol. |
| 81 | + |
| 82 | +Every communication flow is as follows where steps #2, #3, and #4 run inside MM: |
| 83 | + |
| 84 | +1. Non-MM code modifies the `CommBuffer` and triggers MMI. |
| 85 | +2. `StandaloneMmCore` copies the content to the shadowed one in MMRAM and calls the corresponding MMI handler. |
| 86 | +3. MMI handler accesses the shadowed `CommBuffer` in MMRAM. |
| 87 | +4. Upon returning of the MMI handler, `StandaloneMmCore` copies the updated content in the shadowed buffer to the `CommBuffer` in non-MMRAM. |
| 88 | +5. Upon returning to non-MM mode, non-MM code reads the `CommBuffer`. |
| 89 | + |
| 90 | +By following the above, the `CommBuffer` used by the Communication PPI/Protocol is referred to as the **Primary Buffer**. Additionally, other non-MMRAM memory for specific MM driver usage are termed **Non-Primary Buffer**. Those buffer can be pointed from the MM HOBs, or pointed from the `CommBuffer`. Both the Primary Buffer and Non-Primary Buffer used by MM drivers should be validated for accessibility before use. |
| 91 | + |
| 92 | +## Non-MMRAM Access |
| 93 | + |
| 94 | +Any memory outside of the MMRAM (non-MMRAM) that needs to be accessed by MMI handlers must be explicitly declared as "Unblock Mem" through `MmUnblockMemoryRequest()` (`MdePkg/Include/Library/MmUnblockMemoryLib.h`). |
| 95 | + |
| 96 | +Requirements for marking the non-MMRAM as "Unblocked": |
| 97 | + |
| 98 | +1. The memory must be allocated and unblocked in the Post-Mem phase and before the gEfiPeiMmCommunicationPpiGuid is installed. |
| 99 | +2. The memory must be runtime-accessible and cannot be reclaimed by the OS. |
| 100 | + |
| 101 | +`StandaloneMmIpl` builds the corresponding `EFI_HOB_RESOURCE_DESCRIPTOR` in the MM HOB list for all unblocked non-MMRAM memory access. Any non-MMRAM memory region that is not described by `EFI_HOB_RESOURCE_DESCRIPTOR` in the MM HOB list is not accessible from SMM mode. |
| 102 | + |
| 103 | +## MM HOBs |
| 104 | + |
| 105 | +PEI HOBs are used by the traditional SMM. The lifecycle of traditional SMM HOBs is limited to the boot phase, and once entering the runtime phase, HOBs can no longer be accessed or used in the SMM. In contrast, Standalone MM is designed to maintain the validity of its self-owned HOBs throughout the entire lifecycle, including the runtime phase. |
| 106 | + |
| 107 | +`StandaloneMmIpl` is not required to pass the entire PEI HOB list to the SMM foundation. Instead, it must create and pass a specific subset of HOBs that are essential for the operation of the Standalone MM environment. Overall, MM self-owned HOBs can be divided into two categories: **MM Foundation HOBs** and **MM Platform HOBs**. |
| 108 | + |
| 109 | +### MM Foundation HOBs |
| 110 | + |
| 111 | +The MM Foundation HOBs are a set of HOBs that are created by the common logic within the `StandaloneMmIpl`. These HOBs provide the necessary information about the firmware environment and memory regions that the MM Core and drivers will interact with. The following HOBs are created by `StandaloneMmIpl` common logic; hence, they should **NOT** be created by the platform part: |
| 112 | + |
| 113 | +- Single GUIDed (`gEfiSmmSmramMemoryGuid`) HOB to describe the MM regions. |
| 114 | +- Single `EFI_HOB_TYPE_MEMORY_ALLOCATION` (`gEfiHobMemoryAllocModuleGuid`) HOB to describe the MM region of MM Core. |
| 115 | +- Single `EFI_HOB_TYPE_FV` to describe the BFV where MM Core resides if there is no MM FV HOB created by the platform. |
| 116 | +- Multiple `EFI_HOB_RESOURCE_DESCRIPTOR` HOBs to describe the non-MM regions and their access permissions. All accessible non-MM regions should be described by `EFI_HOB_RESOURCE_DESCRIPTOR` HOBs. |
| 117 | +- Single `EFI_HOB_TYPE_MEMORY_ALLOCATION` (`gMmProfileDataHobGuid`) HOB to describe the MM profile data region. This region is to log the non-MM regions marked with the `MM_RESOURCE_ATTRIBUTE_LOGGING` attribute in `EFI_HOB_RESOURCE_DESCRIPTOR` HOBs once they are accessed in MM. |
| 118 | +- Single GUIDed (`gMmCommBufferHobGuid`) HOB to identify the MM Communication buffer (`CommBuffer`) in the non-MM region. |
| 119 | +- Multiple GUIDed (`gSmmBaseHobGuid`) HOBs to describe the SMM base address of each processor. |
| 120 | +- Multiple GUIDed (`gMpInformation2HobGuid`) HOBs to describe the MP information. |
| 121 | +- Single GUIDed (`gMmCpuSyncConfigHobGuid`) HOB to describe how BSP synchronizes with APs in x86 SMM. |
| 122 | +- Single GUIDed (`gMmAcpiS3EnableHobGuid`) HOB to describe the ACPI S3 enable status. |
| 123 | +- Single GUIDed (`gEfiAcpiVariableGuid`) HOB to identify the S3 data root region in x86. |
| 124 | +- Single GUIDed (`gMmStatusCodeUseSerialHobGuid`) HOB to describe whether the status code uses the serial port or not. |
| 125 | + |
| 126 | +### MM Platform HOBs |
| 127 | + |
| 128 | +In addition to the MM Foundation HOBs, the `StandaloneMmIpl` will consume the `MmPlatformHobProducerLib/CreateMmPlatformHob()` to create platform-specific HOBs that are necessary for the Standalone MM environment. These HOBs provide information and configuration details that are unique to the platform on which the system is running. The creation of these HOBs ensures that the MM environment is properly configured to interact with the platform's hardware and firmware features. |
| 129 | + |
| 130 | +## Communication between SMM/Non-SMM |
| 131 | +The following mechanisms are provided for communication between SMM and Non-SMM: |
| 132 | + |
| 133 | +1. Using `CommBuffer` with Protocol `EFI_MM_COMMUNICATION_PROTOCOL` or PPI `EFI_PEI_MM_COMMUNICATION_PPI`: |
| 134 | + - Requires dependency on the `EFI_MM_COMMUNICATION_PROTOCOL` or `EFI_PEI_MM_COMMUNICATION_PPI`. |
| 135 | + - Triggers an SMI when sharing data between SMM and Non-SMM code. |
| 136 | + |
| 137 | +2. Using "Unblock Mem": |
| 138 | + - Must meet the usage requirements. Refer to the **Non-MMRAM Access** section for details. |
| 139 | + |
| 140 | +3. Using MM Guided HOBs: |
| 141 | + - For data sizes < 64KB: Embed the data directly into the HOB. |
| 142 | + |
| 143 | +Option #1 is suitable when the data cannot be finalized before launching MM or when the data flow is bidirectional between SMM and Non-SMM code. Option #2 is necessary for ASL code to pass data to the SW SMI handler. It is also an alternative solution to avoid triggering an SMI for latency considerations. Option #3 is ideal when the data size is small than 64K and it can be finalized before launching MM and the data flow is unidirectional between SMM and Non-SMM code. |
| 144 | + |
| 145 | +But in cases where silicon initialization code does not want to rely on the communication PPI, the data size to be passed to MM exceeds 64KB, and the memory cannot be runtime-accessible due to the requirement for Runtime Non-SMM invisibility, then options #1 and #2 are not applicable. Option #3 requires splitting the data into multiple Guided HOBs, which increases code complexity due to the need to reassemble the data in MM. To simplify this, a fourth solution was introduced: |
| 146 | + |
| 147 | +4. Using MM Memory Allocation HOBs with BSData and Non-Zero GUID: |
| 148 | + - Memory Producer (PEIM): Create a Memory Allocation HOB pointing to a BSData memory region and assign a Non-Zero GUID to the corresponding HOB. |
| 149 | + - MM Core: Migrate the Memory Allocation HOB into MMRAM by copying the data from Non-MMRAM to MMRAM. Refer to `MigrateMemoryAllocationHobs()` in `Edk2/StandaloneMmPkg/Core/StandaloneMmCore.c`. |
| 150 | + - Memory Consumer (MM Drivers): Retrieve the memory from the Memory Allocation HOB using its assigned Non-Zero GUID. |
| 151 | + |
| 152 | +## Memory Protection |
| 153 | + |
| 154 | +The `PiSmmCpuStandaloneMm` driver creates a page table used in MM mode according to the `EFI_HOB_RESOURCE_DESCRIPTOR` in the MM HOB list. The newly created page table controls memory accessibility in MM. |
| 155 | + |
| 156 | +The following table outlines the differences in memory protection policies between the traditional SMM and the Standalone MM. This comparison is particularly relevant for x86 systems and highlights the security enhancements provided by Standalone MM. |
| 157 | + |
| 158 | +| Items | Policy | SMM | MM | |
| 159 | +|------------------------------|---------------------------------------------|------------------------------|------------------------------| |
| 160 | +| **DRAM** | CommBuffer & Unblock Mem: non-executable, Writable. Others Mem: Non-Present | EndOfDxe | End of CpuMm.Entrypoint | |
| 161 | +| **MMIO** | Non-Executable, Writable | EndOfDxe | End of CpuMm.Entrypoint | |
| 162 | +| **SMRAM** | Code: Read-only, Executable. Data: Writable, non-executable | EndOfDxe | End of MmIpl.Entrypoint | |
| 163 | +| **Code Check (MSR[4E0h].BIT2)** | Forbidden call-out | EndOfDxe | End of CpuMm.Entrypoint | |
| 164 | +| **SMRR (MSR[1F2h])** | Forbidden access-in | End of CpuMm.Entrypoint | End of CpuMm.Entrypoint | |
| 165 | +| **SMM Paging State (MSR[141h].BIT0)** | Lock SMM paging state | EndOfDxe | End of MmIpl.Entrypoint | |
| 166 | + |
| 167 | +###### Table 1: SMM and MM Memory Protection Policy |
0 commit comments