BOOLEAN mCpuSmmRestrictedMemoryAccess;\r
X86_ASSEMBLY_PATCH_LABEL gPatch5LevelPagingNeeded;\r
\r
-/**\r
- Disable CET.\r
-**/\r
-VOID\r
-EFIAPI\r
-DisableCet (\r
- VOID\r
- );\r
-\r
-/**\r
- Enable CET.\r
-**/\r
-VOID\r
-EFIAPI\r
-EnableCet (\r
- VOID\r
- );\r
-\r
/**\r
Check if 1-GByte pages is supported by processor or not.\r
\r
ReleaseSpinLock (mPFLock);\r
}\r
\r
-/**\r
- This function sets memory attribute for page table.\r
-**/\r
-VOID\r
-SetPageTableAttributes (\r
- VOID\r
- )\r
-{\r
- UINTN Index2;\r
- UINTN Index3;\r
- UINTN Index4;\r
- UINTN Index5;\r
- UINT64 *L1PageTable;\r
- UINT64 *L2PageTable;\r
- UINT64 *L3PageTable;\r
- UINT64 *L4PageTable;\r
- UINT64 *L5PageTable;\r
- UINTN PageTableBase;\r
- BOOLEAN IsSplitted;\r
- BOOLEAN PageTableSplitted;\r
- BOOLEAN CetEnabled;\r
- BOOLEAN Enable5LevelPaging;\r
- IA32_CR4 Cr4;\r
-\r
- //\r
- // Don't mark page table memory as read-only if\r
- // - no restriction on access to non-SMRAM memory; or\r
- // - SMM heap guard feature enabled; or\r
- // BIT2: SMM page guard enabled\r
- // BIT3: SMM pool guard enabled\r
- // - SMM profile feature enabled\r
- //\r
- if (!mCpuSmmRestrictedMemoryAccess ||\r
- ((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0) ||\r
- FeaturePcdGet (PcdCpuSmmProfileEnable))\r
- {\r
- //\r
- // Restriction on access to non-SMRAM memory and heap guard could not be enabled at the same time.\r
- //\r
- ASSERT (\r
- !(mCpuSmmRestrictedMemoryAccess &&\r
- (PcdGet8 (PcdHeapGuardPropertyMask) & (BIT3 | BIT2)) != 0)\r
- );\r
-\r
- //\r
- // Restriction on access to non-SMRAM memory and SMM profile could not be enabled at the same time.\r
- //\r
- ASSERT (!(mCpuSmmRestrictedMemoryAccess && FeaturePcdGet (PcdCpuSmmProfileEnable)));\r
- return;\r
- }\r
-\r
- DEBUG ((DEBUG_INFO, "SetPageTableAttributes\n"));\r
-\r
- //\r
- // Disable write protection, because we need mark page table to be write protected.\r
- // We need *write* page table memory, to mark itself to be *read only*.\r
- //\r
- CetEnabled = ((AsmReadCr4 () & CR4_CET_ENABLE) != 0) ? TRUE : FALSE;\r
- if (CetEnabled) {\r
- //\r
- // CET must be disabled if WP is disabled.\r
- //\r
- DisableCet ();\r
- }\r
-\r
- AsmWriteCr0 (AsmReadCr0 () & ~CR0_WP);\r
-\r
- do {\r
- DEBUG ((DEBUG_INFO, "Start...\n"));\r
- PageTableSplitted = FALSE;\r
- L5PageTable = NULL;\r
-\r
- PageTableBase = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;\r
- Cr4.UintN = AsmReadCr4 ();\r
- Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1);\r
-\r
- if (Enable5LevelPaging) {\r
- L5PageTable = (UINT64 *)PageTableBase;\r
- SmmSetMemoryAttributesEx (PageTableBase, Enable5LevelPaging, (EFI_PHYSICAL_ADDRESS)PageTableBase, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
- PageTableSplitted = (PageTableSplitted || IsSplitted);\r
- }\r
-\r
- for (Index5 = 0; Index5 < (Enable5LevelPaging ? SIZE_4KB/sizeof (UINT64) : 1); Index5++) {\r
- if (Enable5LevelPaging) {\r
- L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
- if (L4PageTable == NULL) {\r
- continue;\r
- }\r
- } else {\r
- L4PageTable = (UINT64 *)PageTableBase;\r
- }\r
-\r
- SmmSetMemoryAttributesEx (PageTableBase, Enable5LevelPaging, (EFI_PHYSICAL_ADDRESS)(UINTN)L4PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
- PageTableSplitted = (PageTableSplitted || IsSplitted);\r
-\r
- for (Index4 = 0; Index4 < SIZE_4KB/sizeof (UINT64); Index4++) {\r
- L3PageTable = (UINT64 *)(UINTN)(L4PageTable[Index4] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
- if (L3PageTable == NULL) {\r
- continue;\r
- }\r
-\r
- SmmSetMemoryAttributesEx (PageTableBase, Enable5LevelPaging, (EFI_PHYSICAL_ADDRESS)(UINTN)L3PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
- PageTableSplitted = (PageTableSplitted || IsSplitted);\r
-\r
- for (Index3 = 0; Index3 < SIZE_4KB/sizeof (UINT64); Index3++) {\r
- if ((L3PageTable[Index3] & IA32_PG_PS) != 0) {\r
- // 1G\r
- continue;\r
- }\r
-\r
- L2PageTable = (UINT64 *)(UINTN)(L3PageTable[Index3] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
- if (L2PageTable == NULL) {\r
- continue;\r
- }\r
-\r
- SmmSetMemoryAttributesEx (PageTableBase, Enable5LevelPaging, (EFI_PHYSICAL_ADDRESS)(UINTN)L2PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
- PageTableSplitted = (PageTableSplitted || IsSplitted);\r
-\r
- for (Index2 = 0; Index2 < SIZE_4KB/sizeof (UINT64); Index2++) {\r
- if ((L2PageTable[Index2] & IA32_PG_PS) != 0) {\r
- // 2M\r
- continue;\r
- }\r
-\r
- L1PageTable = (UINT64 *)(UINTN)(L2PageTable[Index2] & ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
- if (L1PageTable == NULL) {\r
- continue;\r
- }\r
-\r
- SmmSetMemoryAttributesEx (PageTableBase, Enable5LevelPaging, (EFI_PHYSICAL_ADDRESS)(UINTN)L1PageTable, SIZE_4KB, EFI_MEMORY_RO, &IsSplitted);\r
- PageTableSplitted = (PageTableSplitted || IsSplitted);\r
- }\r
- }\r
- }\r
- }\r
- } while (PageTableSplitted);\r
-\r
- //\r
- // Enable write protection, after page table updated.\r
- //\r
- AsmWriteCr0 (AsmReadCr0 () | CR0_WP);\r
- if (CetEnabled) {\r
- //\r
- // re-enable CET.\r
- //\r
- EnableCet ();\r
- }\r
-\r
- return;\r
-}\r
-\r
/**\r
This function reads CR2 register when on-demand paging is enabled.\r
\r