UefiCpuPkg: Simplify the code to set smm page table as RO
Simplify the code to set memory used by smm page table as RO. Since memory used by smm page table are in PageTablePool list, we only need to set all PageTablePool as ReadOnly in smm page table itself. Also, we only need to flush tlb once after setting all page table pool as Read Only. Signed-off-by: Dun Tan <dun.tan@intel.com> Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com>
This commit is contained in:
@@ -202,111 +202,6 @@ Exit:
|
||||
ReleaseSpinLock (mPFLock);
|
||||
}
|
||||
|
||||
/**
|
||||
This function sets memory attribute for page table.
|
||||
**/
|
||||
VOID
|
||||
SetPageTableAttributes (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINTN Index2;
|
||||
UINTN Index3;
|
||||
UINT64 *L1PageTable;
|
||||
UINT64 *L2PageTable;
|
||||
UINT64 *L3PageTable;
|
||||
UINTN PageTableBase;
|
||||
BOOLEAN IsSplitted;
|
||||
BOOLEAN PageTableSplitted;
|
||||
BOOLEAN CetEnabled;
|
||||
|
||||
//
|
||||
// Don't mark page table to read-only if heap guard is enabled.
|
||||
//
|
||||
// BIT2: SMM page guard enabled
|
||||
// BIT3: SMM pool guard enabled
|
||||
//
|
||||
if ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) {
|
||||
DEBUG ((DEBUG_INFO, "Don't mark page table to read-only as heap guard is enabled\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Don't mark page table to read-only if SMM profile is enabled.
|
||||
//
|
||||
if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
|
||||
DEBUG ((DEBUG_INFO, "Don't mark page table to read-only as SMM profile is enabled\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n"));
|
||||
|
||||
//
|
||||
// Disable write protection, because we need mark page table to be write protected.
|
||||
// We need *write* page table memory, to mark itself to be *read only*.
|
||||
//
|
||||
CetEnabled = ((AsmReadCr4 () & CR4_CET_ENABLE) != 0) ? TRUE : FALSE;
|
||||
if (CetEnabled) {
|
||||
//
|
||||
// CET must be disabled if WP is disabled.
|
||||
//
|
||||
DisableCet ();
|
||||
}
|
||||
|
||||
AsmWriteCr0 (AsmReadCr0 () & ~CR0_WP);
|
||||
|
||||
do {
|
||||
DEBUG ((DEBUG_INFO, "Start...\n"));
|
||||
PageTableSplitted = FALSE;
|
||||
|
||||
PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
|
||||
L3PageTable = (UINT64 *)PageTableBase;
|
||||
|
||||
SmmSetMemoryAttributesEx (PageTableBase, FALSE, (EFI_PHYSICAL_ADDRESS)PageTableBase, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);
|
||||
PageTableSplitted = (PageTableSplitted || IsSplitted);
|
||||
|
||||
for (Index3 = 0; Index3 < 4; Index3++) {
|
||||
L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);
|
||||
if (L2PageTable == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SmmSetMemoryAttributesEx (PageTableBase, FALSE, (EFI_PHYSICAL_ADDRESS)(UINTN)L2PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);
|
||||
PageTableSplitted = (PageTableSplitted || IsSplitted);
|
||||
|
||||
for (Index2 = 0; Index2 < SIZE_4KB/sizeof (UINT64); Index2++) {
|
||||
if ((L2PageTable[Index2] & IA32_PG_PS) != 0) {
|
||||
// 2M
|
||||
continue;
|
||||
}
|
||||
|
||||
L1PageTable = (UINT64 *)(UINTN)(L2PageTable[Index2] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);
|
||||
if (L1PageTable == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SmmSetMemoryAttributesEx (PageTableBase, FALSE, (EFI_PHYSICAL_ADDRESS)(UINTN)L1PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);
|
||||
PageTableSplitted = (PageTableSplitted || IsSplitted);
|
||||
}
|
||||
}
|
||||
} while (PageTableSplitted);
|
||||
|
||||
//
|
||||
// Enable write protection, after page table updated.
|
||||
//
|
||||
AsmWriteCr0 (AsmReadCr0 () | CR0_WP);
|
||||
if (CetEnabled) {
|
||||
//
|
||||
// re-enable CET.
|
||||
//
|
||||
EnableCet ();
|
||||
}
|
||||
|
||||
mIsReadOnlyPageTable = TRUE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
This function returns with no action for 32 bit.
|
||||
|
||||
|
Reference in New Issue
Block a user