UefiCpuPkg/PiSmmCpuDxeSmm: Impl CreateExtendedProtectionRange for MM

According Standalone MM design, all accessible NON-MMRAM memory shall
be in ResourceDescriptor HOBs. So, This patch consumes the Resource
HOBs to create extended protection MemoryRegion and add them into
protected memory ranges.

Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Dun Tan <dun.tan@intel.com>
Cc: Hongbin1 Zhang <hongbin1.zhang@intel.com>
Cc: Wei6 Xu <wei6.xu@intel.com>
Cc: Yuanhao Xie <yuanhao.xie@intel.com>
This commit is contained in:
Jiaxin Wu 2024-06-26 13:04:57 +08:00 committed by mergify[bot]
parent 614d6c91bf
commit ee54bda382
2 changed files with 86 additions and 2 deletions

View File

@ -45,3 +45,86 @@ GetSmmProfileData (
return SmmProfileDataHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress;
}
/**
Build Memory Region from ResourceDescriptor HOBs by excluding Logging attribute range.
@param[out] MemoryRegion Returned Non-Mmram Memory regions.
@param[out] MemoryRegionCount A pointer to the number of Memory regions.
**/
VOID
BuildMemoryMapFromResDescHobs (
OUT MM_CPU_MEMORY_REGION **MemoryRegion,
OUT UINTN *MemoryRegionCount
)
{
EFI_PEI_HOB_POINTERS Hob;
UINTN Count;
UINTN Index;
ASSERT (MemoryRegion != NULL && MemoryRegionCount != NULL);
*MemoryRegion = NULL;
*MemoryRegionCount = 0;
//
// Get the count.
//
Count = 0;
Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
while (Hob.Raw != NULL) {
if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) == 0) {
//
// Resource HOBs describe all accessible non-smram regions.
// Logging attribute range is treated as not present. Not-present ranges are not included in this memory map.
//
Count++;
}
Hob.Raw = GET_NEXT_HOB (Hob);
Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
}
*MemoryRegionCount = Count;
*MemoryRegion = (MM_CPU_MEMORY_REGION *)AllocateZeroPool (sizeof (MM_CPU_MEMORY_REGION) * Count);
ASSERT (*MemoryRegion != NULL);
Index = 0;
Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
while (Hob.Raw != NULL) {
if ((Hob.ResourceDescriptor->ResourceAttribute & MM_RESOURCE_ATTRIBUTE_LOGGING) == 0) {
ASSERT (Index < Count);
(*MemoryRegion)[Index].Base = Hob.ResourceDescriptor->PhysicalStart;
(*MemoryRegion)[Index].Length = Hob.ResourceDescriptor->ResourceLength;
(*MemoryRegion)[Index].Attribute = EFI_MEMORY_XP;
if (Hob.ResourceDescriptor->ResourceAttribute == EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED) {
(*MemoryRegion)[Index].Attribute |= EFI_MEMORY_RO;
}
Index++;
}
Hob.Raw = GET_NEXT_HOB (Hob);
Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
}
return;
}
/**
Build extended protection MemoryRegion.
The caller is responsible for freeing MemoryRegion via FreePool().
@param[out] MemoryRegion Returned Non-Mmram Memory regions.
@param[out] MemoryRegionCount A pointer to the number of Memory regions.
**/
VOID
CreateExtendedProtectionRange (
OUT MM_CPU_MEMORY_REGION **MemoryRegion,
OUT UINTN *MemoryRegionCount
)
{
BuildMemoryMapFromResDescHobs (MemoryRegion, MemoryRegionCount);
}

View File

@ -428,6 +428,7 @@ InitProtectedMemRange (
// Create extended protection MemoryRegion and add them into protected memory ranges.
// Retrieve the accessible regions when SMM profile is enabled.
// In SMM: only MMIO is accessible.
// In MM: all regions described by resource HOBs are accessible.
//
CreateExtendedProtectionRange (&MemoryRegion, &MemoryRegionCount);
ASSERT (MemoryRegion != NULL);
@ -475,7 +476,7 @@ InitProtectedMemRange (
}
//
// Create MMIO ranges which are set to present and execution-disable.
// Create protection ranges which are set to present and execution-disable.
//
for (Index = 0; Index < MemoryRegionCount; Index++) {
mProtectionMemRange[NumberOfProtectRange].Range.Base = MemoryRegion[Index].Base;
@ -505,7 +506,7 @@ InitProtectedMemRange (
NumberOfProtectRange = mProtectionMemRangeCount;
for (Index = 0; Index < NumberOfProtectRange; Index++) {
//
// If MMIO base address is not 2MB alignment, make 2MB alignment for create 4KB page in page table.
// If base address is not 2MB alignment, make 2MB alignment for create 4KB page in page table.
//
ProtectBaseAddress = mProtectionMemRange[Index].Range.Base;
ProtectEndAddress = mProtectionMemRange[Index].Range.Top;