Skip to content

Commit c287214

Browse files
NingFengGitmergify[bot]
authored andcommitted
MedModulePkg/DxeIplPeim: Fix pagetable protection region in 5 level paging
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4873 Currently the function does not cover the 5 level paging case. it will casued pagetable protection region set incorrectly. This patch do the enhancemant and with the patch protection region has been set correctly. Signed-off-by: Ning Feng <ning.feng@intel.com> Cc: Ray Ni <ray.ni@intel.com>
1 parent 13fad60 commit c287214

File tree

3 files changed

+37
-31
lines changed

3 files changed

+37
-31
lines changed

MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ Create4GPageTablesIa32Pae (
166166
// Protect the page table by marking the memory used for page table to be
167167
// read-only.
168168
//
169-
EnablePageTableProtection ((UINTN)PageMap, FALSE);
169+
EnablePageTableProtection ((UINTN)PageMap, 3);
170170

171171
return (UINTN)PageMap;
172172
}

MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -485,14 +485,14 @@ Split1GPageTo2M (
485485
486486
@param[in] PageTableBase Base address of page table (CR3).
487487
@param[in] Address Start address of a page to be set as read-only.
488-
@param[in] Level4Paging Level 4 paging flag.
488+
@param[in] LevelOfPaging Level of paging.
489489
490490
**/
491491
VOID
492492
SetPageTablePoolReadOnly (
493493
IN UINTN PageTableBase,
494494
IN EFI_PHYSICAL_ADDRESS Address,
495-
IN BOOLEAN Level4Paging
495+
IN UINT8 LevelOfPaging
496496
)
497497
{
498498
UINTN Index;
@@ -502,9 +502,9 @@ SetPageTablePoolReadOnly (
502502
UINT64 *PageTable;
503503
UINT64 *NewPageTable;
504504
UINT64 PageAttr;
505-
UINT64 LevelSize[5];
506-
UINT64 LevelMask[5];
507-
UINTN LevelShift[5];
505+
UINT64 LevelSize[6];
506+
UINT64 LevelMask[6];
507+
UINTN LevelShift[6];
508508
UINTN Level;
509509
UINT64 PoolUnitSize;
510510

@@ -521,23 +521,26 @@ SetPageTablePoolReadOnly (
521521
LevelShift[2] = PAGING_L2_ADDRESS_SHIFT;
522522
LevelShift[3] = PAGING_L3_ADDRESS_SHIFT;
523523
LevelShift[4] = PAGING_L4_ADDRESS_SHIFT;
524+
LevelShift[5] = PAGING_L5_ADDRESS_SHIFT;
524525

525526
LevelMask[1] = PAGING_4K_ADDRESS_MASK_64;
526527
LevelMask[2] = PAGING_2M_ADDRESS_MASK_64;
527528
LevelMask[3] = PAGING_1G_ADDRESS_MASK_64;
528-
LevelMask[4] = PAGING_1G_ADDRESS_MASK_64;
529+
LevelMask[4] = PAGING_512G_ADDRESS_MASK_64;
530+
LevelMask[5] = PAGING_256T_ADDRESS_MASK_64;
529531

530532
LevelSize[1] = SIZE_4KB;
531533
LevelSize[2] = SIZE_2MB;
532534
LevelSize[3] = SIZE_1GB;
533535
LevelSize[4] = SIZE_512GB;
536+
LevelSize[5] = SIZE_256TB;
534537

535538
AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
536539
PAGING_1G_ADDRESS_MASK_64;
537540
PageTable = (UINT64 *)(UINTN)PageTableBase;
538541
PoolUnitSize = PAGE_TABLE_POOL_UNIT_SIZE;
539542

540-
for (Level = (Level4Paging) ? 4 : 3; Level > 0; --Level) {
543+
for (Level = LevelOfPaging; Level > 0; --Level) {
541544
Index = ((UINTN)RShiftU64 (Address, LevelShift[Level]));
542545
Index &= PAGING_PAE_INDEX_MASK;
543546

@@ -607,13 +610,13 @@ SetPageTablePoolReadOnly (
607610
Prevent the memory pages used for page table from been overwritten.
608611
609612
@param[in] PageTableBase Base address of page table (CR3).
610-
@param[in] Level4Paging Level 4 paging flag.
613+
@param[in] LevelOfPaging Level of paging.
611614
612615
**/
613616
VOID
614617
EnablePageTableProtection (
615-
IN UINTN PageTableBase,
616-
IN BOOLEAN Level4Paging
618+
IN UINTN PageTableBase,
619+
IN UINT8 LevelOfPaging
617620
)
618621
{
619622
PAGE_TABLE_POOL *HeadPool;
@@ -642,7 +645,7 @@ EnablePageTableProtection (
642645
// protection to them one by one.
643646
//
644647
while (PoolSize > 0) {
645-
SetPageTablePoolReadOnly (PageTableBase, Address, Level4Paging);
648+
SetPageTablePoolReadOnly (PageTableBase, Address, LevelOfPaging);
646649
Address += PAGE_TABLE_POOL_UNIT_SIZE;
647650
PoolSize -= PAGE_TABLE_POOL_UNIT_SIZE;
648651
}
@@ -696,7 +699,7 @@ CreateIdentityMappingPageTables (
696699
UINTN TotalPagesNum;
697700
UINTN BigPageAddress;
698701
VOID *Hob;
699-
BOOLEAN Page5LevelEnabled;
702+
UINT8 LevelOfPaging;
700703
BOOLEAN Page1GSupport;
701704
PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
702705
UINT64 AddressEncMask;
@@ -743,16 +746,16 @@ CreateIdentityMappingPageTables (
743746
//
744747
// If cpu has already run in 64bit long mode PEI, Page table Level in DXE must align with previous level.
745748
//
746-
Cr4.UintN = AsmReadCr4 ();
747-
Page5LevelEnabled = (Cr4.Bits.LA57 != 0);
748-
if (Page5LevelEnabled) {
749+
Cr4.UintN = AsmReadCr4 ();
750+
LevelOfPaging = (Cr4.Bits.LA57 == 1) ? 5 : 4;
751+
if (LevelOfPaging == 5) {
749752
ASSERT (PcdGetBool (PcdUse5LevelPageTable));
750753
}
751754
} else {
752755
//
753756
// If cpu runs in 32bit protected mode PEI, Page table Level in DXE is decided by PCD and feature capability.
754757
//
755-
Page5LevelEnabled = FALSE;
758+
LevelOfPaging = 4;
756759
if (PcdGetBool (PcdUse5LevelPageTable)) {
757760
AsmCpuidEx (
758761
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS,
@@ -763,20 +766,20 @@ CreateIdentityMappingPageTables (
763766
NULL
764767
);
765768
if (EcxFlags.Bits.FiveLevelPage != 0) {
766-
Page5LevelEnabled = TRUE;
769+
LevelOfPaging = 5;
767770
}
768771
}
769772
}
770773

771-
DEBUG ((DEBUG_INFO, "AddressBits=%u 5LevelPaging=%u 1GPage=%u\n", PhysicalAddressBits, Page5LevelEnabled, Page1GSupport));
774+
DEBUG ((DEBUG_INFO, "AddressBits=%u LevelOfPaging=%u 1GPage=%u\n", PhysicalAddressBits, LevelOfPaging, Page1GSupport));
772775

773776
//
774777
// IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses
775778
// when 5-Level Paging is disabled,
776779
// due to either unsupported by HW, or disabled by PCD.
777780
//
778781
ASSERT (PhysicalAddressBits <= 52);
779-
if (!Page5LevelEnabled && (PhysicalAddressBits > 48)) {
782+
if ((LevelOfPaging != 5) && (PhysicalAddressBits > 48)) {
780783
PhysicalAddressBits = 48;
781784
}
782785

@@ -811,7 +814,7 @@ CreateIdentityMappingPageTables (
811814
//
812815
// Substract the one page occupied by PML5 entries if 5-Level Paging is disabled.
813816
//
814-
if (!Page5LevelEnabled) {
817+
if (LevelOfPaging != 5) {
815818
TotalPagesNum--;
816819
}
817820

@@ -831,7 +834,7 @@ CreateIdentityMappingPageTables (
831834
// By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
832835
//
833836
PageMap = (VOID *)BigPageAddress;
834-
if (Page5LevelEnabled) {
837+
if (LevelOfPaging == 5) {
835838
//
836839
// By architecture only one PageMapLevel5 exists - so lets allocate storage for it.
837840
//
@@ -853,7 +856,7 @@ CreateIdentityMappingPageTables (
853856
PageMapLevel4Entry = (VOID *)BigPageAddress;
854857
BigPageAddress += SIZE_4KB;
855858

856-
if (Page5LevelEnabled) {
859+
if (LevelOfPaging == 5) {
857860
//
858861
// Make a PML5 Entry
859862
//
@@ -947,7 +950,7 @@ CreateIdentityMappingPageTables (
947950
ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));
948951
}
949952

950-
if (Page5LevelEnabled) {
953+
if (LevelOfPaging == 5) {
951954
Cr4.UintN = AsmReadCr4 ();
952955
Cr4.Bits.LA57 = 1;
953956
AsmWriteCr4 (Cr4.UintN);
@@ -961,7 +964,7 @@ CreateIdentityMappingPageTables (
961964
// Protect the page table by marking the memory used for page table to be
962965
// read-only.
963966
//
964-
EnablePageTableProtection ((UINTN)PageMap, TRUE);
967+
EnablePageTableProtection ((UINTN)PageMap, LevelOfPaging);
965968

966969
//
967970
// Set IA32_EFER.NXE if necessary.

MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,17 @@ typedef union {
149149

150150
#define PAGING_PAE_INDEX_MASK 0x1FF
151151

152-
#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
153-
#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull
154-
#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
152+
#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
153+
#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull
154+
#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull
155+
#define PAGING_512G_ADDRESS_MASK_64 0x000FF80000000000ull
156+
#define PAGING_256T_ADDRESS_MASK_64 0x000F800000000000ull
155157

156158
#define PAGING_L1_ADDRESS_SHIFT 12
157159
#define PAGING_L2_ADDRESS_SHIFT 21
158160
#define PAGING_L3_ADDRESS_SHIFT 30
159161
#define PAGING_L4_ADDRESS_SHIFT 39
162+
#define PAGING_L5_ADDRESS_SHIFT 48
160163

161164
#define PAGING_PML4E_NUMBER 4
162165

@@ -293,13 +296,13 @@ IsNullDetectionEnabled (
293296
Prevent the memory pages used for page table from been overwritten.
294297
295298
@param[in] PageTableBase Base address of page table (CR3).
296-
@param[in] Level4Paging Level 4 paging flag.
299+
@param[in] LevelOfPaging Level of paging.
297300
298301
**/
299302
VOID
300303
EnablePageTableProtection (
301-
IN UINTN PageTableBase,
302-
IN BOOLEAN Level4Paging
304+
IN UINTN PageTableBase,
305+
IN UINT8 LevelOfPaging
303306
);
304307

305308
/**

0 commit comments

Comments
 (0)