Thanks. Looks good to me. Reviewed-by: Jiewen Yao From: Kun Qin Sent: Thursday, January 21, 2021 9:44 AM To: devel@edk2.groups.io; Yao, Jiewen Cc: Ard Biesheuvel ; Sami Mujawar ; Supreeth Venkatesh Subject: RE: [edk2-devel] [PATCH v3 05/18] StandaloneMmPkg: StandaloneMmMemLib: Extends support for X64 architecture Hi Jiewen, Do you have further concerns about this specific patch? I did created a Bugzilla ticket to track the OS memory protection concern here: 3168 - Add non-MMRAM memory protection for Standalone MM environment (tianocore.org). It introduces a new proposal to allow access of DXE/RT regions from MMRAM, but requires non trivial change. Please let me know if you hold different opinions towards the proposal or this patch. Thanks, Kun From: Kun Qin Sent: Thursday, January 14, 2021 14:36 To: devel@edk2.groups.io Cc: Ard Biesheuvel; Sami Mujawar; Jiewen Yao; Supreeth Venkatesh Subject: [edk2-devel] [PATCH v3 05/18] StandaloneMmPkg: StandaloneMmMemLib: Extends support for X64 architecture This change extends StandaloneMmMemLib library to support X64 architecture. The implementation is ported from MdePkg/Library/SmmMemLib. Cc: Ard Biesheuvel > Cc: Sami Mujawar > Cc: Jiewen Yao > Cc: Supreeth Venkatesh > Signed-off-by: Kun Qin > --- Notes: v3: - Updated destructor description of varibales to pass CI build. v2: - Added routine to fix bug of not initializing MmRanges [Jiewen] - Extends support to x86 instead of x64 only [Hao] StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c | 27 ++++ StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c | 52 +++++++ StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c | 155 ++++++++++++++++++++ StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf | 13 +- 4 files changed, 246 insertions(+), 1 deletion(-) diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c index cb7c5e677a6b..4124959e0435 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c +++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c @@ -40,4 +40,31 @@ MmMemLibInternalCalculateMaximumSupportAddress ( DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress)); } +/** + Initialize cached Mmram Ranges from HOB. + + @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information. + @retval EFI_SUCCESS MmRanges are populated successfully. + +**/ +EFI_STATUS +MmMemLibInternalPopulateMmramRanges ( + VOID + ) +{ + // Not implemented for AARCH64. + return EFI_SUCCESS; +} + +/** + Deinitialize cached Mmram Ranges. + +**/ +VOID +MmMemLibInternalFreeMmramRanges ( + VOID + ) +{ + // Not implemented for AARCH64. +} diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c index b533bd8390cd..2737f95315eb 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c +++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c @@ -37,6 +37,27 @@ MmMemLibInternalCalculateMaximumSupportAddress ( VOID ); +/** + Initialize cached Mmram Ranges from HOB. + + @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information. + @retval EFI_SUCCESS MmRanges are populated successfully. + +**/ +EFI_STATUS +MmMemLibInternalPopulateMmramRanges ( + VOID + ); + +/** + Deinitialize cached Mmram Ranges. + +**/ +VOID +MmMemLibInternalFreeMmramRanges ( + VOID + ); + /** This function check if the buffer is valid per processor architecture and not overlap with MMRAM. @@ -253,11 +274,42 @@ MemLibConstructor ( IN EFI_MM_SYSTEM_TABLE *MmSystemTable ) { + EFI_STATUS Status; // // Calculate and save maximum support address // MmMemLibInternalCalculateMaximumSupportAddress (); + // + // Initialize cached Mmram Ranges from HOB. + // + Status = MmMemLibInternalPopulateMmramRanges (); + + return Status; +} + +/** + Destructor for Mm Mem library. + + @param ImageHandle The image handle of the process. + @param MmSystemTable The EFI System Table pointer. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +MemLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_MM_SYSTEM_TABLE *MmSystemTable + ) +{ + + // + // Deinitialize cached Mmram Ranges. + // + MmMemLibInternalFreeMmramRanges (); + return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c new file mode 100644 index 000000000000..1a978541716a --- /dev/null +++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c @@ -0,0 +1,155 @@ +/** @file + Internal ARCH Specific file of MM memory check library. + + MM memory check library implementation. This library consumes MM_ACCESS_PROTOCOL + to get MMRAM information. In order to use this library instance, the platform should produce + all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core + and MM driver) and/or specific dedicated hardware. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ Copyright (c) Microsoft Corporation. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include + +#include +#include + +// +// Maximum support address used to check input buffer +// +extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress; +extern EFI_MMRAM_DESCRIPTOR *mMmMemLibInternalMmramRanges; +extern UINTN mMmMemLibInternalMmramCount; + +/** + Calculate and save the maximum support address. + +**/ +VOID +MmMemLibInternalCalculateMaximumSupportAddress ( + VOID + ) +{ + VOID *Hob; + UINT32 RegEax; + UINT8 PhysicalAddressBits; + + // + // Get physical address bits supported. + // + Hob = GetFirstHob (EFI_HOB_TYPE_CPU); + if (Hob != NULL) { + PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace; + } else { + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000008) { + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); + PhysicalAddressBits = (UINT8) RegEax; + } else { + PhysicalAddressBits = 36; + } + } + // + // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses. + // + ASSERT (PhysicalAddressBits <= 52); + if (PhysicalAddressBits > 48) { + PhysicalAddressBits = 48; + } + + // + // Save the maximum support address in one global variable + // + mMmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1); + DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress)); +} + +/** + Initialize cached Mmram Ranges from HOB. + + @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information. + @retval EFI_SUCCESS MmRanges are populated successfully. + +**/ +EFI_STATUS +MmMemLibInternalPopulateMmramRanges ( + VOID + ) +{ + 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; + + HobStart = GetHobList (); + DEBUG ((DEBUG_INFO, "%a - 0x%x\n", __FUNCTION__, HobStart)); + + // + // 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); + 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; + } + + mMmMemLibInternalMmramRanges = AllocatePool (mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR)); + if (mMmMemLibInternalMmramRanges) { + CopyMem (mMmMemLibInternalMmramRanges, + MmramDescriptors, + mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR)); + } + + return EFI_SUCCESS; +} + +/** + Deinitialize cached Mmram Ranges. + +**/ +VOID +MmMemLibInternalFreeMmramRanges ( + VOID + ) +{ + if (mMmMemLibInternalMmramRanges != NULL) { + FreePool (mMmMemLibInternalMmramRanges); + } +} + diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf index 49da02e54e6d..062b0d7a1161 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf +++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf @@ -8,6 +8,7 @@ # # Copyright (c) 2015, Intel Corporation. All rights reserved.
# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+# Copyright (c) Microsoft Corporation. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -22,16 +23,20 @@ [Defines] PI_SPECIFICATION_VERSION = 0x00010032 LIBRARY_CLASS = MemLib|MM_STANDALONE MM_CORE_STANDALONE CONSTRUCTOR = MemLibConstructor + DESTRUCTOR = MemLibDestructor # # The following information is for reference only and not required by the build tools. # -# VALID_ARCHITECTURES = AARCH64 +# VALID_ARCHITECTURES = IA32 X64 AARCH64 # [Sources.Common] StandaloneMmMemLib.c +[Sources.IA32, Sources.X64] + X86StandaloneMmMemLibInternal.c + [Sources.AARCH64] AArch64/StandaloneMmMemLibInternal.c @@ -42,3 +47,9 @@ [Packages] [LibraryClasses] BaseMemoryLib DebugLib + HobLib + MemoryAllocationLib + +[Guids] + gMmCoreDataHobGuid ## SOMETIMES_CONSUMES ## HOB + gEfiMmPeiMmramMemoryReserveGuid ## SOMETIMES_CONSUMES ## HOB -- 2.30.0.windows.1