Skip to content

Commit 0f3867f

Browse files
NingFengGitmergify[bot]
authored andcommitted
UefiPayloadPkg/UefiPayloadEntry: Fix PT protection 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 c287214 commit 0f3867f

File tree

3 files changed

+34
-28
lines changed

3 files changed

+34
-28
lines changed

UefiPayloadPkg/UefiPayloadEntry/Ia32/DxeLoadFunc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ Create4GPageTablesIa32Pae (
177177
// Protect the page table by marking the memory used for page table to be
178178
// read-only.
179179
//
180-
EnablePageTableProtection ((UINTN)PageMap, FALSE);
180+
EnablePageTableProtection ((UINTN)PageMap, 3);
181181

182182
return (UINTN)PageMap;
183183
}

UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -481,14 +481,14 @@ Split1GPageTo2M (
481481
482482
@param[in] PageTableBase Base address of page table (CR3).
483483
@param[in] Address Start address of a page to be set as read-only.
484-
@param[in] Level4Paging Level 4 paging flag.
484+
@param[in] LevelOfPaging Level of paging.
485485
486486
**/
487487
VOID
488488
SetPageTablePoolReadOnly (
489489
IN UINTN PageTableBase,
490490
IN EFI_PHYSICAL_ADDRESS Address,
491-
IN BOOLEAN Level4Paging
491+
IN UINT8 LevelOfPaging
492492
)
493493
{
494494
UINTN Index;
@@ -498,9 +498,9 @@ SetPageTablePoolReadOnly (
498498
UINT64 *PageTable;
499499
UINT64 *NewPageTable;
500500
UINT64 PageAttr;
501-
UINT64 LevelSize[5];
502-
UINT64 LevelMask[5];
503-
UINTN LevelShift[5];
501+
UINT64 LevelSize[6];
502+
UINT64 LevelMask[6];
503+
UINTN LevelShift[6];
504504
UINTN Level;
505505
UINT64 PoolUnitSize;
506506

@@ -517,23 +517,26 @@ SetPageTablePoolReadOnly (
517517
LevelShift[2] = PAGING_L2_ADDRESS_SHIFT;
518518
LevelShift[3] = PAGING_L3_ADDRESS_SHIFT;
519519
LevelShift[4] = PAGING_L4_ADDRESS_SHIFT;
520+
LevelShift[5] = PAGING_L5_ADDRESS_SHIFT;
520521

521522
LevelMask[1] = PAGING_4K_ADDRESS_MASK_64;
522523
LevelMask[2] = PAGING_2M_ADDRESS_MASK_64;
523524
LevelMask[3] = PAGING_1G_ADDRESS_MASK_64;
524-
LevelMask[4] = PAGING_1G_ADDRESS_MASK_64;
525+
LevelMask[4] = PAGING_512G_ADDRESS_MASK_64;
526+
LevelMask[5] = PAGING_256T_ADDRESS_MASK_64;
525527

526528
LevelSize[1] = SIZE_4KB;
527529
LevelSize[2] = SIZE_2MB;
528530
LevelSize[3] = SIZE_1GB;
529531
LevelSize[4] = SIZE_512GB;
532+
LevelSize[5] = SIZE_256TB;
530533

531534
AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) &
532535
PAGING_1G_ADDRESS_MASK_64;
533536
PageTable = (UINT64 *)(UINTN)PageTableBase;
534537
PoolUnitSize = PAGE_TABLE_POOL_UNIT_SIZE;
535538

536-
for (Level = (Level4Paging) ? 4 : 3; Level > 0; --Level) {
539+
for (Level = LevelOfPaging; Level > 0; --Level) {
537540
Index = ((UINTN)RShiftU64 (Address, LevelShift[Level]));
538541
Index &= PAGING_PAE_INDEX_MASK;
539542

@@ -603,13 +606,13 @@ SetPageTablePoolReadOnly (
603606
Prevent the memory pages used for page table from been overwritten.
604607
605608
@param[in] PageTableBase Base address of page table (CR3).
606-
@param[in] Level4Paging Level 4 paging flag.
609+
@param[in] LevelOfPaging Level of paging.
607610
608611
**/
609612
VOID
610613
EnablePageTableProtection (
611-
IN UINTN PageTableBase,
612-
IN BOOLEAN Level4Paging
614+
IN UINTN PageTableBase,
615+
IN UINT8 LevelOfPaging
613616
)
614617
{
615618
PAGE_TABLE_POOL *HeadPool;
@@ -638,7 +641,7 @@ EnablePageTableProtection (
638641
// protection to them one by one.
639642
//
640643
while (PoolSize > 0) {
641-
SetPageTablePoolReadOnly (PageTableBase, Address, Level4Paging);
644+
SetPageTablePoolReadOnly (PageTableBase, Address, LevelOfPaging);
642645
Address += PAGE_TABLE_POOL_UNIT_SIZE;
643646
PoolSize -= PAGE_TABLE_POOL_UNIT_SIZE;
644647
}
@@ -691,7 +694,7 @@ CreateIdentityMappingPageTables (
691694
UINTN TotalPagesNum;
692695
UINTN BigPageAddress;
693696
VOID *Hob;
694-
BOOLEAN Enable5LevelPaging;
697+
UINT8 LevelOfPaging;
695698
BOOLEAN Page1GSupport;
696699
PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
697700
UINT64 AddressEncMask;
@@ -740,18 +743,18 @@ CreateIdentityMappingPageTables (
740743
// below logic inherits the 5-level paging setting from bootloader in IA-32e mode
741744
// and uses 4-level paging in legacy protected mode.
742745
//
743-
Cr4.UintN = AsmReadCr4 ();
744-
Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1);
746+
Cr4.UintN = AsmReadCr4 ();
747+
LevelOfPaging = (Cr4.Bits.LA57 == 1) ? 5 : 4;
745748

746-
DEBUG ((DEBUG_INFO, "PayloadEntry: AddressBits=%u 5LevelPaging=%u 1GPage=%u\n", PhysicalAddressBits, Enable5LevelPaging, Page1GSupport));
749+
DEBUG ((DEBUG_INFO, "PayloadEntry: AddressBits=%u LevelOfPaging=%u 1GPage=%u\n", PhysicalAddressBits, LevelOfPaging, Page1GSupport));
747750

748751
//
749752
// IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses
750753
// when 5-Level Paging is disabled,
751754
// due to either unsupported by HW, or disabled by PCD.
752755
//
753756
ASSERT (PhysicalAddressBits <= 52);
754-
if (!Enable5LevelPaging && (PhysicalAddressBits > 48)) {
757+
if ((LevelOfPaging != 5) && (PhysicalAddressBits > 48)) {
755758
PhysicalAddressBits = 48;
756759
}
757760

@@ -786,7 +789,7 @@ CreateIdentityMappingPageTables (
786789
//
787790
// Substract the one page occupied by PML5 entries if 5-Level Paging is disabled.
788791
//
789-
if (!Enable5LevelPaging) {
792+
if (LevelOfPaging != 5) {
790793
TotalPagesNum--;
791794
}
792795

@@ -806,7 +809,7 @@ CreateIdentityMappingPageTables (
806809
// By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
807810
//
808811
PageMap = (VOID *)BigPageAddress;
809-
if (Enable5LevelPaging) {
812+
if (LevelOfPaging == 5) {
810813
//
811814
// By architecture only one PageMapLevel5 exists - so lets allocate storage for it.
812815
//
@@ -828,7 +831,7 @@ CreateIdentityMappingPageTables (
828831
PageMapLevel4Entry = (VOID *)BigPageAddress;
829832
BigPageAddress += SIZE_4KB;
830833

831-
if (Enable5LevelPaging) {
834+
if (LevelOfPaging == 5) {
832835
//
833836
// Make a PML5 Entry
834837
//
@@ -922,7 +925,7 @@ CreateIdentityMappingPageTables (
922925
ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));
923926
}
924927

925-
if (Enable5LevelPaging) {
928+
if (LevelOfPaging == 5) {
926929
//
927930
// For the PML5 entries we are not using fill in a null entry.
928931
//
@@ -933,7 +936,7 @@ CreateIdentityMappingPageTables (
933936
// Protect the page table by marking the memory used for page table to be
934937
// read-only.
935938
//
936-
EnablePageTableProtection ((UINTN)PageMap, TRUE);
939+
EnablePageTableProtection ((UINTN)PageMap, LevelOfPaging);
937940

938941
//
939942
// Set IA32_EFER.NXE if necessary.

UefiPayloadPkg/UefiPayloadEntry/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)