Skip to content

Commit

Permalink
StandaloneMmPkg/MmIpl: Correct unblocked memory regions attribute
Browse files Browse the repository at this point in the history
When CPU smm profile feature was enabled, unblocked memory should
not set logging attribute when building resource HOB.

Signed-off-by: Hongbin1 Zhang <[email protected]>
Cc: Jiewen Yao <[email protected]>
Cc: Ray Ni <[email protected]>
Cc: Star Zeng <[email protected]>
Cc: Jiaxin Wu <[email protected]>
Cc: Wei6 Xu <[email protected]>
Cc: Sami Mujawar <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: Supreeth Venkatesh <[email protected]>
  • Loading branch information
hongbin123 committed Sep 9, 2024
1 parent e571571 commit 8035052
Showing 1 changed file with 87 additions and 27 deletions.
114 changes: 87 additions & 27 deletions StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,44 @@ MmIplBuildResourceHobForUnblockedRegion (
*HobBufferSize = UsedSize;
}

/**
Collect unblock memory regions.
@param[in, out] MemoryRegion Pointer to unblock memory regions.
@param[in, out] MemoryRegionCount Count of unblock memory regions.
**/
VOID
CollectUnblockMemoryRegions (
IN OUT MM_IPL_MEMORY_REGION *MemoryRegion,
IN OUT UINTN *MemoryRegionCount
)
{
UINTN Index;
EFI_HOB_GENERIC_HEADER *GuidHob;
MM_UNBLOCK_REGION *UnblockRegion;

ASSERT (MemoryRegionCount != NULL);
ASSERT (*MemoryRegionCount == 0 || MemoryRegion != NULL);

Index = 0;
//
// Collect unblock memory ranges
//
GuidHob = GetFirstGuidHob (&gMmUnblockRegionHobGuid);
while (GuidHob != NULL) {
if (Index < *MemoryRegionCount) {
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));
}

*MemoryRegionCount = Index;
}

/**
Create MMIO memory map according to platform HOB.
Expand Down Expand Up @@ -564,16 +602,15 @@ 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, Unblock 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.
**/
VOID
MmIplBuildResourceHobForAllSystemMemory (
Expand All @@ -593,6 +630,7 @@ MmIplBuildResourceHobForAllSystemMemory (
UINT64 MaxAddress;
MM_IPL_MEMORY_REGION *MemoryRegions;
MM_IPL_MEMORY_REGION SortBuffer;
UINTN UnblockRegionCount;

MaxAddress = LShiftU64 (1, MmIplCalculateMaximumSupportAddress ());

Expand All @@ -605,9 +643,16 @@ MmIplBuildResourceHobForAllSystemMemory (
}

//
// Allocate buffer for platform memory regions, MM Profile data, MMRam ranges, an extra terminator.
// Get the count of platform memory regions
//
UnblockRegionCount = 0;
CollectUnblockMemoryRegions (NULL, &UnblockRegionCount);

//
// 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) {
Expand All @@ -629,24 +674,31 @@ MmIplBuildResourceHobForAllSystemMemory (
CollectPlatformMemoryRegions (PlatformHobList, PlatformHobSize, MemoryRegions, &PlatformRegionCount);
}

//
// Collect unblock memory regions
//
if (UnblockRegionCount != 0) {
CollectUnblockMemoryRegions (&MemoryRegions[PlatformRegionCount], &UnblockRegionCount);
}

//
// 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;
Expand Down Expand Up @@ -843,24 +895,32 @@ CreateMmFoundationHobList (
UsedSize += HobLength;
}

//
// Build resource HOB for unblocked region
//
HobLength = GetRemainingHobSize (*FoundationHobSize, UsedSize);
if (PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)) {
//
// Only unblocked memory regions are accessible
//
MmIplBuildResourceHobForUnblockedRegion (FoundationHobList + UsedSize, &HobLength);
} else {
MmIplBuildResourceHobForUnblockedRegion (FoundationHobList + UsedSize, &HobLength);
UsedSize += HobLength;

if (!PcdGetBool (PcdCpuSmmRestrictedMemoryAccess)) {
//
// All system memory (DRAM) is accessible.
// When SMM Profile is enabled:
// * Access to regions reported from MmPlatformHobProducerLib do not require logging.
// * Access to regions included all Mmram ranges, MM Profile data, Unblock memory ranges and MMIO ranges 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
);
UsedSize += HobLength;
}

UsedSize += HobLength;

if (*FoundationHobSize < UsedSize) {
Status = RETURN_BUFFER_TOO_SMALL;
} else {
Expand Down

0 comments on commit 8035052

Please sign in to comment.