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 Aug 29, 2024
1 parent 31f0225 commit e1b285f
Showing 1 changed file with 111 additions and 27 deletions.
138 changes: 111 additions & 27 deletions StandaloneMmPkg/Drivers/StandaloneMmIplPei/MmFoundationHob.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit e1b285f

Please sign in to comment.