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>
This commit is contained in:
parent
d480f106a6
commit
0c037b5fa7
|
@ -523,3 +523,81 @@ IsSmmCommBufferForbiddenAddress (
|
||||||
|
|
||||||
return FALSE;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -479,6 +479,21 @@ extern UINT64 mAddressEncMask;
|
||||||
extern UINT64 mTimeoutTicker;
|
extern UINT64 mTimeoutTicker;
|
||||||
extern UINT64 mTimeoutTicker2;
|
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.
|
Create 4G PageTable in SMRAM.
|
||||||
|
|
||||||
|
@ -940,6 +955,21 @@ IsSmmCommBufferForbiddenAddress (
|
||||||
IN UINT64 Address
|
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.
|
This function caches the UEFI memory map information.
|
||||||
**/
|
**/
|
||||||
|
|
|
@ -405,11 +405,11 @@ InitProtectedMemRange (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINTN NumberOfDescriptors;
|
MM_CPU_MEMORY_REGION *MemoryRegion;
|
||||||
|
UINTN MemoryRegionCount;
|
||||||
UINTN NumberOfAddedDescriptors;
|
UINTN NumberOfAddedDescriptors;
|
||||||
UINTN NumberOfProtectRange;
|
UINTN NumberOfProtectRange;
|
||||||
UINTN NumberOfSpliteRange;
|
UINTN NumberOfSpliteRange;
|
||||||
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
|
|
||||||
UINTN TotalSize;
|
UINTN TotalSize;
|
||||||
EFI_PHYSICAL_ADDRESS ProtectBaseAddress;
|
EFI_PHYSICAL_ADDRESS ProtectBaseAddress;
|
||||||
EFI_PHYSICAL_ADDRESS ProtectEndAddress;
|
EFI_PHYSICAL_ADDRESS ProtectEndAddress;
|
||||||
|
@ -419,40 +419,23 @@ InitProtectedMemRange (
|
||||||
UINT64 Low4KBPageSize;
|
UINT64 Low4KBPageSize;
|
||||||
MEMORY_PROTECTION_RANGE MemProtectionRange;
|
MEMORY_PROTECTION_RANGE MemProtectionRange;
|
||||||
|
|
||||||
NumberOfDescriptors = 0;
|
MemoryRegion = NULL;
|
||||||
|
MemoryRegionCount = 0;
|
||||||
NumberOfAddedDescriptors = mSmmCpuSmramRangeCount;
|
NumberOfAddedDescriptors = mSmmCpuSmramRangeCount;
|
||||||
NumberOfSpliteRange = 0;
|
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 (
|
CreateExtendedProtectionRange (&MemoryRegion, &MemoryRegionCount);
|
||||||
&NumberOfDescriptors,
|
ASSERT (MemoryRegion != NULL);
|
||||||
&MemorySpaceMap
|
|
||||||
);
|
NumberOfAddedDescriptors += MemoryRegionCount;
|
||||||
for (Index = 0; Index < NumberOfDescriptors; Index++) {
|
|
||||||
if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {
|
ASSERT (NumberOfAddedDescriptors != 0);
|
||||||
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
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NumberOfAddedDescriptors != 0) {
|
|
||||||
TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);
|
TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);
|
||||||
mProtectionMemRange = (MEMORY_PROTECTION_RANGE *)AllocateZeroPool (TotalSize);
|
mProtectionMemRange = (MEMORY_PROTECTION_RANGE *)AllocateZeroPool (TotalSize);
|
||||||
ASSERT (mProtectionMemRange != NULL);
|
ASSERT (mProtectionMemRange != NULL);
|
||||||
|
@ -494,17 +477,19 @@ InitProtectedMemRange (
|
||||||
//
|
//
|
||||||
// Create MMIO ranges which are set to present and execution-disable.
|
// Create MMIO ranges which are set to present and execution-disable.
|
||||||
//
|
//
|
||||||
for (Index = 0; Index < NumberOfDescriptors; Index++) {
|
for (Index = 0; Index < MemoryRegionCount; Index++) {
|
||||||
if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&
|
mProtectionMemRange[NumberOfProtectRange].Range.Base = MemoryRegion[Index].Base;
|
||||||
ADDRESS_IS_ALIGNED (MemorySpaceMap[Index].BaseAddress, SIZE_4KB) &&
|
mProtectionMemRange[NumberOfProtectRange].Range.Top = MemoryRegion[Index].Base + MemoryRegion[Index].Length;
|
||||||
(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].Present = TRUE;
|
||||||
mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;
|
mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;
|
||||||
NumberOfProtectRange++;
|
NumberOfProtectRange++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free the MemoryRegion
|
||||||
|
//
|
||||||
|
if (MemoryRegion != NULL) {
|
||||||
|
FreePool (MemoryRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -512,7 +497,6 @@ InitProtectedMemRange (
|
||||||
//
|
//
|
||||||
ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount);
|
ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount);
|
||||||
mProtectionMemRangeCount = NumberOfProtectRange;
|
mProtectionMemRangeCount = NumberOfProtectRange;
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// According to protected ranges, create the ranges which will be mapped by 2KB page.
|
// According to protected ranges, create the ranges which will be mapped by 2KB page.
|
||||||
|
|
Loading…
Reference in New Issue