From e1b285f0ac7fe1b7786418cd8066e7fa6d8daec4 Mon Sep 17 00:00:00 2001 From: Hongbin1 Zhang Date: Thu, 29 Aug 2024 09:52:05 +0800 Subject: [PATCH] StandaloneMmPkg/MmIpl: Correct unblocked memory regions attribute When CPU smm profile feature was enabled, unblocked memory should not set logging attribute when building resource HOB. Signed-off-by: Hongbin1 Zhang Cc: Jiewen Yao Cc: Ray Ni Cc: Star Zeng Cc: Jiaxin Wu Cc: Wei6 Xu Cc: Sami Mujawar Cc: Ard Biesheuvel Cc: Supreeth Venkatesh --- .../StandaloneMmIplPei/MmFoundationHob.c | 138 ++++++++++++++---- 1 file changed, 111 insertions(+), 27 deletions(-) diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c index b13d4f688f007..c9108e96dbf28 100644 --- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c +++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c @@ -450,6 +450,66 @@ MmIplBuildResourceHobForUnblockedRegion ( *HobBufferSize = UsedSize; } +/** + Collect unblocked memory regions. + + @param[out] MemoryRegionCount Count of unblocked memory regions. + @return MM_IPL_MEMORY_REGION Pointer of Unblocked memory regions. +**/ +MM_IPL_MEMORY_REGION * +CollectUnblockedMemoryRegions ( + OUT UINTN *MemoryRegionCount + ) +{ + UINTN Index; + EFI_HOB_GENERIC_HEADER *GuidHob; + MM_UNBLOCK_REGION *UnblockRegion; + MM_IPL_MEMORY_REGION *MemoryRegion; + + ASSERT (MemoryRegionCount != NULL); + + Index = 0; + MemoryRegion = NULL; + + // + // Get unblock memory ranges count + // + GuidHob = GetFirstGuidHob (&gMmUnblockRegionHobGuid); + while (GuidHob != NULL) { + UnblockRegion = GET_GUID_HOB_DATA (GuidHob); + Index++; + GuidHob = GetNextGuidHob (&gMmUnblockRegionHobGuid, GET_NEXT_HOB (GuidHob)); + } + + *MemoryRegionCount = Index; + + if (*MemoryRegionCount != 0) { + MemoryRegion = AllocatePages (EFI_SIZE_TO_PAGES (*MemoryRegionCount * sizeof (MM_IPL_MEMORY_REGION))); + } else { + return NULL; + } + + if (MemoryRegion != NULL) { + Index = 0; + + // + // Collect unblock memory ranges + // + GuidHob = GetFirstGuidHob (&gMmUnblockRegionHobGuid); + while (GuidHob != NULL) { + UnblockRegion = GET_GUID_HOB_DATA (GuidHob); + MemoryRegion[Index].Base = UnblockRegion->PhysicalStart; + MemoryRegion[Index].Length = EFI_PAGES_TO_SIZE (UnblockRegion->NumberOfPages); + Index++; + GuidHob = GetNextGuidHob (&gMmUnblockRegionHobGuid, GET_NEXT_HOB (GuidHob)); + } + + ASSERT (*MemoryRegionCount == Index); + } + + return MemoryRegion; +} + /** Create MMIO memory map according to platform HOB. @@ -564,15 +624,17 @@ MmIplCalculateMaximumSupportAddress ( /** Build resource HOB to cover [0, PhysicalAddressBits length] by excluding - all Mmram ranges, MM Profile data and MMIO ranges. - - @param[in] HobBuffer 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] PlatformHobList Platform HOB list. - @param[in] PlatformHobSize Platform HOB size. - @param[in] Block Pointer of MMRAM descriptor block. - @param[in] MmProfileDataHob Pointer to MM profile data HOB. + all Mmram ranges, MM Profile data, Unblocked memory ranges and MMIO ranges. + + @param[in] HobBuffer 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] PlatformHobList Platform HOB list. + @param[in] PlatformHobSize Platform HOB size. + @param[in] Block Pointer of MMRAM descriptor block. + @param[in] MmProfileDataHob Pointer to MM profile data HOB. + @param[in] UnblockRegion Pointer to unblocked memory region. + @param[in] UnblockRegionCount Count of unblocked memory regions. **/ VOID @@ -582,7 +644,9 @@ MmIplBuildResourceHobForAllSystemMemory ( IN VOID *PlatformHobList, IN UINTN PlatformHobSize, IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block, - IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob + IN EFI_HOB_MEMORY_ALLOCATION *MmProfileDataHob, + IN MM_IPL_MEMORY_REGION *UnblockRegion, + IN UINTN UnblockRegionCount ) { UINTN Index; @@ -605,9 +669,10 @@ MmIplBuildResourceHobForAllSystemMemory ( } // - // Allocate buffer for platform memory regions, MM Profile data, MMRam ranges, an extra terminator. + // Allocate buffer for platform memory regions, unblock memory regions, + // MM Profile data, MMRam ranges, an extra terminator. // - Count = PlatformRegionCount + Block->NumberOfMmReservedRegions + ((MmProfileDataHob != NULL) ? 1 : 0) + 1; + Count = PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions + ((MmProfileDataHob != NULL) ? 1 : 0) + 1; MemoryRegions = AllocatePages (EFI_SIZE_TO_PAGES (Count * sizeof (*MemoryRegions))); ASSERT (MemoryRegions != NULL); if (MemoryRegions == NULL) { @@ -629,24 +694,31 @@ MmIplBuildResourceHobForAllSystemMemory ( CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, MemoryRegions, &PlatformRegionCount); } + // + // Collect unblocked memory regions + // + if (UnblockRegionCount != 0) { + CopyMem (&MemoryRegions[PlatformRegionCount], UnblockRegion, (UnblockRegionCount * sizeof (MM_IPL_MEMORY_REGION))); + } + // // Collect SMRAM regions // for (Index = 0; Index < Block->NumberOfMmReservedRegions; Index++) { - MemoryRegions[PlatformRegionCount + Index].Base = Block->Descriptor[Index].CpuStart; - MemoryRegions[PlatformRegionCount + Index].Length = Block->Descriptor[Index].PhysicalSize; + MemoryRegions[PlatformRegionCount + UnblockRegionCount + Index].Base = Block->Descriptor[Index].CpuStart; + MemoryRegions[PlatformRegionCount + UnblockRegionCount + Index].Length = Block->Descriptor[Index].PhysicalSize; } // // Collect MM profile database region // if (MmProfileDataHob != NULL) { - MemoryRegions[PlatformRegionCount + Block->NumberOfMmReservedRegions].Base = MmProfileDataHob->AllocDescriptor.MemoryBaseAddress; - MemoryRegions[PlatformRegionCount + Block->NumberOfMmReservedRegions].Length = MmProfileDataHob->AllocDescriptor.MemoryLength; + MemoryRegions[PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions].Base = MmProfileDataHob->AllocDescriptor.MemoryBaseAddress; + MemoryRegions[PlatformRegionCount + UnblockRegionCount + Block->NumberOfMmReservedRegions].Length = MmProfileDataHob->AllocDescriptor.MemoryLength; } // - // Build system memory resource HOBs excluding platform memory regions, SMRAM regions, MmProfile database. + // Build system memory resource HOBs excluding platform memory regions, SMRAM regions, MmProfile database, Unblocked memory regions. // QuickSort (MemoryRegions, Count, sizeof (*MemoryRegions), MemoryRegionBaseAddressCompare, &SortBuffer); UsedSize = 0; @@ -740,9 +812,11 @@ CreateMmFoundationHobList ( IN EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *Block ) { - UINTN UsedSize; - RETURN_STATUS Status; - UINTN HobLength; + UINTN UsedSize; + RETURN_STATUS Status; + UINTN HobLength; + UINTN UnblockRegionCount; + MM_IPL_MEMORY_REGION *UnblockRegion; ASSERT (FoundationHobSize != NULL); @@ -843,23 +917,33 @@ CreateMmFoundationHobList ( UsedSize += HobLength; } + // + // Build resource HOB for unblocked region + // HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); - if (PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)) { + MmIplBuildResourceHobForUnblockedRegion (FoundationHobList + UsedSize, &HobLength); + UsedSize += HobLength; + + if (!PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)) { + UnblockRegion = NULL; // - // Only unblocked memory regions are accessible + // Collect unblocked memory regions // - MmIplBuildResourceHobForUnblockedRegion (FoundationHobList + UsedSize, &HobLength); - } else { + UnblockRegion = CollectUnblockedMemoryRegions (&UnblockRegionCount); // // All system memory (DRAM) is accessible. // When SMM Profile is enabled: // * Access to regions reported from MmPlatformHobProducerLib do not require logging. // * Access to other system memory requires logging. // - MmIplBuildResourceHobForAllSystemMemory (FoundationHobList + UsedSize, &HobLength, PlatformHobList, PlatformHobSize, Block, MmProfileDataHob); - } + HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize); + MmIplBuildResourceHobForAllSystemMemory (FoundationHobList + UsedSize, &HobLength, PlatformHobList, PlatformHobSize, Block, MmProfileDataHob, UnblockRegion, UnblockRegionCount); + UsedSize += HobLength; - UsedSize += HobLength; + if (UnblockRegion != NULL) { + FreePages (UnblockRegion, EFI_SIZE_TO_PAGES (UnblockRegionCount * sizeof (MM_IPL_MEMORY_REGION))); + } + } if (*FoundationHobSize < UsedSize) { Status = RETURN_BUFFER_TOO_SMALL;