|
@@ -1139,159 +1139,6 @@ Exit:
|
|
|
ReleaseSpinLock (mPFLock);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- This function sets memory attribute for page table.
|
|
|
-**/
|
|
|
-VOID
|
|
|
-SetPageTableAttributes (
|
|
|
- VOID
|
|
|
- )
|
|
|
-{
|
|
|
- UINTN Index2;
|
|
|
- UINTN Index3;
|
|
|
- UINTN Index4;
|
|
|
- UINTN Index5;
|
|
|
- UINT64 *L1PageTable;
|
|
|
- UINT64 *L2PageTable;
|
|
|
- UINT64 *L3PageTable;
|
|
|
- UINT64 *L4PageTable;
|
|
|
- UINT64 *L5PageTable;
|
|
|
- UINTN PageTableBase;
|
|
|
- BOOLEAN IsSplitted;
|
|
|
- BOOLEAN PageTableSplitted;
|
|
|
- BOOLEAN CetEnabled;
|
|
|
- BOOLEAN Enable5LevelPaging;
|
|
|
- IA32_CR4 Cr4;
|
|
|
-
|
|
|
- //
|
|
|
- // Don't mark page table memory as read-only if
|
|
|
- // - no restriction on access to non-SMRAM memory; or
|
|
|
- // - SMM heap guard feature enabled; or
|
|
|
- // BIT2: SMM page guard enabled
|
|
|
- // BIT3: SMM pool guard enabled
|
|
|
- // - SMM profile feature enabled
|
|
|
- //
|
|
|
- if (!mCpuSmmRestrictedMemoryAccess ||
|
|
|
- ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) ||
|
|
|
- FeaturePcdGet (PcdCpuSmmProfileEnable))
|
|
|
- {
|
|
|
- //
|
|
|
- // Restriction on access to non-SMRAM memory and heap guard could not be enabled at the same time.
|
|
|
- //
|
|
|
- ASSERT (
|
|
|
- !(mCpuSmmRestrictedMemoryAccess &&
|
|
|
- (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0)
|
|
|
- );
|
|
|
-
|
|
|
- //
|
|
|
- // Restriction on access to non-SMRAM memory and SMM profile could not be enabled at the same time.
|
|
|
- //
|
|
|
- ASSERT (!(mCpuSmmRestrictedMemoryAccess && FeaturePcdGet (PcdCpuSmmProfileEnable)));
|
|
|
- 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;
|
|
|
- L5PageTable = NULL;
|
|
|
-
|
|
|
- PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
|
|
|
- Cr4.UintN = AsmReadCr4 ();
|
|
|
- Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1);
|
|
|
-
|
|
|
- if (Enable5LevelPaging) {
|
|
|
- L5PageTable = (UINT64 *)PageTableBase;
|
|
|
- SmmSetMemoryAttributesEx (PageTableBase, Enable5LevelPaging, (EFI_PHYSICAL_ADDRESS)PageTableBase, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);
|
|
|
- PageTableSplitted = (PageTableSplitted || IsSplitted);
|
|
|
- }
|
|
|
-
|
|
|
- for (Index5 = 0; Index5 < (Enable5LevelPaging ? SIZE_4KB/sizeof (UINT64) : 1); Index5++) {
|
|
|
- if (Enable5LevelPaging) {
|
|
|
- L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);
|
|
|
- if (L4PageTable == NULL) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- } else {
|
|
|
- L4PageTable = (UINT64 *)PageTableBase;
|
|
|
- }
|
|
|
-
|
|
|
- SmmSetMemoryAttributesEx (PageTableBase, Enable5LevelPaging, (EFI_PHYSICAL_ADDRESS)(UINTN)L4PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);
|
|
|
- PageTableSplitted = (PageTableSplitted || IsSplitted);
|
|
|
-
|
|
|
- for (Index4 = 0; Index4 < SIZE_4KB/sizeof (UINT64); Index4++) {
|
|
|
- L3PageTable = (UINT64 *)(UINTN)(L4PageTable[Index4] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);
|
|
|
- if (L3PageTable == NULL) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- SmmSetMemoryAttributesEx (PageTableBase, Enable5LevelPaging, (EFI_PHYSICAL_ADDRESS)(UINTN)L3PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);
|
|
|
- PageTableSplitted = (PageTableSplitted || IsSplitted);
|
|
|
-
|
|
|
- for (Index3 = 0; Index3 < SIZE_4KB/sizeof (UINT64); Index3++) {
|
|
|
- if ((L3PageTable[Index3] & IA32_PG_PS) != 0) {
|
|
|
- // 1G
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);
|
|
|
- if (L2PageTable == NULL) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- SmmSetMemoryAttributesEx (PageTableBase, Enable5LevelPaging, (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, Enable5LevelPaging, (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 reads CR2 register when on-demand paging is enabled.
|
|
|
|