diff options
author | Jiaxin Wu <jiaxin.wu@intel.com> | 2024-06-24 23:53:34 +0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2024-08-28 15:25:27 +0000 |
commit | 0c037b5fa7d14bc40294b4fa4edd42b4a5111f64 (patch) | |
tree | 7ad09aff585a3bb2069576885b4c6a2ad40b9ea3 /UefiCpuPkg | |
parent | d480f106a6c1ac15d14b0dc803b03c945c71a09e (diff) | |
download | edk2-0c037b5fa7d14bc40294b4fa4edd42b4a5111f64.zip edk2-0c037b5fa7d14bc40294b4fa4edd42b4a5111f64.tar.gz edk2-0c037b5fa7d14bc40294b4fa4edd42b4a5111f64.tar.bz2 |
UefiCpuPkg/PiSmmCpuDxeSmm: Create extended protection MemRegion in func
MM can not use the gDS service, so move the extended protection
MemRegion creation into function. This can make InitProtectedMemRange()
to be a common function for both SMM and MM.
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>
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r-- | UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c | 78 | ||||
-rw-r--r-- | UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 30 | ||||
-rw-r--r-- | UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 174 |
3 files changed, 187 insertions, 95 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c index 4f6f040..be5b333 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/NonMmramMapDxeSmm.c @@ -523,3 +523,81 @@ IsSmmCommBufferForbiddenAddress ( return FALSE;
}
+
+/**
+ Create extended protection MemoryRegion.
+ Return all MMIO ranges that are reported in GCD service at EndOfDxe.
+
+ 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
+ )
+{
+ UINTN Index;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
+ UINTN NumberOfSpaceDescriptors;
+ UINTN MemoryRegionIndex;
+ UINTN Count;
+
+ MemorySpaceMap = NULL;
+ NumberOfSpaceDescriptors = 0;
+ Count = 0;
+
+ ASSERT (MemoryRegion != NULL && MemoryRegionCount != NULL);
+
+ *MemoryRegion = NULL;
+ *MemoryRegionCount = 0;
+
+ //
+ // Get MMIO ranges from GCD.
+ //
+ gDS->GetMemorySpaceMap (
+ &NumberOfSpaceDescriptors,
+ &MemorySpaceMap
+ );
+ for (Index = 0; Index < NumberOfSpaceDescriptors; Index++) {
+ if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {
+ if (ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) &&
+ (MemorySpaceMap[Index].Length % SIZE_4KB == 0))
+ {
+ Count++;
+ } else {
+ //
+ // Skip the MMIO range that BaseAddress and Length are not 4k aligned since
+ // the minimum granularity of the page table is 4k
+ //
+ DEBUG ((
+ DEBUG_WARN,
+ "MMIO range [0x%lx, 0x%lx] is skipped since it is not 4k aligned.\n",
+ MemorySpaceMap[Index].BaseAddress,
+ MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length
+ ));
+ }
+ }
+ }
+
+ *MemoryRegionCount = Count;
+
+ *MemoryRegion = (MM_CPU_MEMORY_REGION *)AllocateZeroPool (sizeof (MM_CPU_MEMORY_REGION) * Count);
+ ASSERT (*MemoryRegion != NULL);
+
+ MemoryRegionIndex = 0;
+ for (Index = 0; Index < NumberOfSpaceDescriptors; Index++) {
+ if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&
+ ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) &&
+ (MemorySpaceMap[Index].Length % SIZE_4KB == 0))
+ {
+ (*MemoryRegion)[MemoryRegionIndex].Base = MemorySpaceMap[Index].BaseAddress;
+ (*MemoryRegion)[MemoryRegionIndex].Length = MemorySpaceMap[Index].Length;
+ MemoryRegionIndex++;
+ }
+ }
+
+ return;
+}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index a5b40f8..ed0badf 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -479,6 +479,21 @@ extern UINT64 mAddressEncMask; extern UINT64 mTimeoutTicker;
extern UINT64 mTimeoutTicker2;
+typedef struct {
+ ///
+ /// Address of the first byte in the memory region.
+ ///
+ EFI_PHYSICAL_ADDRESS Base;
+ ///
+ /// Length in bytes of the memory region.
+ ///
+ UINT64 Length;
+ ///
+ /// Attributes of the memory region
+ ///
+ UINT64 Attribute;
+} MM_CPU_MEMORY_REGION;
+
/**
Create 4G PageTable in SMRAM.
@@ -940,6 +955,21 @@ IsSmmCommBufferForbiddenAddress ( IN UINT64 Address
);
+/*
+ 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
+ );
+
/**
This function caches the UEFI memory map information.
**/
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index e775b7d..a6f7697 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -404,117 +404,101 @@ InitProtectedMemRange ( VOID
)
{
- UINTN Index;
- UINTN NumberOfDescriptors;
- UINTN NumberOfAddedDescriptors;
- UINTN NumberOfProtectRange;
- UINTN NumberOfSpliteRange;
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
- UINTN TotalSize;
- EFI_PHYSICAL_ADDRESS ProtectBaseAddress;
- EFI_PHYSICAL_ADDRESS ProtectEndAddress;
- EFI_PHYSICAL_ADDRESS Top2MBAlignedAddress;
- EFI_PHYSICAL_ADDRESS Base2MBAlignedAddress;
- UINT64 High4KBPageSize;
- UINT64 Low4KBPageSize;
- MEMORY_PROTECTION_RANGE MemProtectionRange;
-
- NumberOfDescriptors = 0;
+ UINTN Index;
+ MM_CPU_MEMORY_REGION *MemoryRegion;
+ UINTN MemoryRegionCount;
+ UINTN NumberOfAddedDescriptors;
+ UINTN NumberOfProtectRange;
+ UINTN NumberOfSpliteRange;
+ UINTN TotalSize;
+ EFI_PHYSICAL_ADDRESS ProtectBaseAddress;
+ EFI_PHYSICAL_ADDRESS ProtectEndAddress;
+ EFI_PHYSICAL_ADDRESS Top2MBAlignedAddress;
+ EFI_PHYSICAL_ADDRESS Base2MBAlignedAddress;
+ UINT64 High4KBPageSize;
+ UINT64 Low4KBPageSize;
+ MEMORY_PROTECTION_RANGE MemProtectionRange;
+
+ MemoryRegion = NULL;
+ MemoryRegionCount = 0;
NumberOfAddedDescriptors = mSmmCpuSmramRangeCount;
NumberOfSpliteRange = 0;
- MemorySpaceMap = NULL;
//
- // Get MMIO ranges from GCD and add them into protected memory ranges.
+ // 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.
//
- gDS->GetMemorySpaceMap (
- &NumberOfDescriptors,
- &MemorySpaceMap
- );
- for (Index = 0; Index < NumberOfDescriptors; Index++) {
- if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {
- if (ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) &&
- (MemorySpaceMap[Index].Length % SIZE_4KB == 0))
- {
- NumberOfAddedDescriptors++;
- } else {
- //
- // Skip the MMIO range that BaseAddress and Length are not 4k aligned since
- // the minimum granularity of the page table is 4k
- //
- DEBUG ((
- DEBUG_WARN,
- "MMIO range [0x%lx, 0x%lx] is skipped since it is not 4k aligned.\n",
- MemorySpaceMap[Index].BaseAddress,
- MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length
- ));
- }
- }
- }
+ CreateExtendedProtectionRange (&MemoryRegion, &MemoryRegionCount);
+ ASSERT (MemoryRegion != NULL);
- if (NumberOfAddedDescriptors != 0) {
- TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);
- mProtectionMemRange = (MEMORY_PROTECTION_RANGE *)AllocateZeroPool (TotalSize);
- ASSERT (mProtectionMemRange != NULL);
- mProtectionMemRangeCount = TotalSize / sizeof (MEMORY_PROTECTION_RANGE);
+ NumberOfAddedDescriptors += MemoryRegionCount;
- //
- // Copy existing ranges.
- //
- CopyMem (mProtectionMemRange, mProtectionMemRangeTemplate, sizeof (mProtectionMemRangeTemplate));
+ ASSERT (NumberOfAddedDescriptors != 0);
- //
- // Create split ranges which come from protected ranges.
- //
- TotalSize = (TotalSize / sizeof (MEMORY_PROTECTION_RANGE)) * sizeof (MEMORY_RANGE);
- mSplitMemRange = (MEMORY_RANGE *)AllocateZeroPool (TotalSize);
- ASSERT (mSplitMemRange != NULL);
+ TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);
+ mProtectionMemRange = (MEMORY_PROTECTION_RANGE *)AllocateZeroPool (TotalSize);
+ ASSERT (mProtectionMemRange != NULL);
+ mProtectionMemRangeCount = TotalSize / sizeof (MEMORY_PROTECTION_RANGE);
- //
- // Create SMM ranges which are set to present and execution-enable.
- //
- NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);
- for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
- if ((mSmmCpuSmramRanges[Index].CpuStart >= mProtectionMemRange[0].Range.Base) &&
- (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize < mProtectionMemRange[0].Range.Top))
- {
- //
- // If the address have been already covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz
- //
- break;
- }
+ //
+ // Copy existing ranges.
+ //
+ CopyMem (mProtectionMemRange, mProtectionMemRangeTemplate, sizeof (mProtectionMemRangeTemplate));
- mProtectionMemRange[NumberOfProtectRange].Range.Base = mSmmCpuSmramRanges[Index].CpuStart;
- mProtectionMemRange[NumberOfProtectRange].Range.Top = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize;
- mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
- mProtectionMemRange[NumberOfProtectRange].Nx = FALSE;
- NumberOfProtectRange++;
- }
+ //
+ // Create split ranges which come from protected ranges.
+ //
+ TotalSize = (TotalSize / sizeof (MEMORY_PROTECTION_RANGE)) * sizeof (MEMORY_RANGE);
+ mSplitMemRange = (MEMORY_RANGE *)AllocateZeroPool (TotalSize);
+ ASSERT (mSplitMemRange != NULL);
- //
- // Create MMIO ranges which are set to present and execution-disable.
- //
- for (Index = 0; Index < NumberOfDescriptors; Index++) {
- if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&
- ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) &&
- (MemorySpaceMap[Index].Length % SIZE_4KB == 0))
- {
- mProtectionMemRange[NumberOfProtectRange].Range.Base = MemorySpaceMap[Index].BaseAddress;
- mProtectionMemRange[NumberOfProtectRange].Range.Top = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length;
- mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
- mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;
- NumberOfProtectRange++;
- }
+ //
+ // Create SMM ranges which are set to present and execution-enable.
+ //
+ NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
+ if ((mSmmCpuSmramRanges[Index].CpuStart >= mProtectionMemRange[0].Range.Base) &&
+ (mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize < mProtectionMemRange[0].Range.Top))
+ {
+ //
+ // If the address have been already covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz
+ //
+ break;
}
- //
- // Check and updated actual protected memory ranges count
- //
- ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount);
- mProtectionMemRangeCount = NumberOfProtectRange;
+ mProtectionMemRange[NumberOfProtectRange].Range.Base = mSmmCpuSmramRanges[Index].CpuStart;
+ mProtectionMemRange[NumberOfProtectRange].Range.Top = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize;
+ mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
+ mProtectionMemRange[NumberOfProtectRange].Nx = FALSE;
+ NumberOfProtectRange++;
}
//
+ // Create MMIO ranges which are set to present and execution-disable.
+ //
+ for (Index = 0; Index < MemoryRegionCount; Index++) {
+ mProtectionMemRange[NumberOfProtectRange].Range.Base = MemoryRegion[Index].Base;
+ mProtectionMemRange[NumberOfProtectRange].Range.Top = MemoryRegion[Index].Base + MemoryRegion[Index].Length;
+ mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
+ mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;
+ NumberOfProtectRange++;
+ }
+
+ //
+ // Free the MemoryRegion
+ //
+ if (MemoryRegion != NULL) {
+ FreePool (MemoryRegion);
+ }
+
+ //
+ // Check and updated actual protected memory ranges count
+ //
+ ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount);
+ mProtectionMemRangeCount = NumberOfProtectRange;
+
+ //
// According to protected ranges, create the ranges which will be mapped by 2KB page.
//
NumberOfSpliteRange = 0;
|