UefiCpuPkg/PiSmmCpuDxeSmm: Iterate page table to find proper entry

Iterate through the page table to find the appropriate page table
entry for page creation if one of the following cases is met:
1) StartBit > EndBit: The PageSize of current entry is bigger than
the platform-specified PageSize granularity.
2) IA32_PG_P bit is 0 & IA32_PG_PS bit is not 0: The current entry
is present and it's a non-leaf entry.

Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
This commit is contained in:
Jiaxin Wu 2024-07-15 11:39:48 +08:00 committed by mergify[bot]
parent 24f8b97a9d
commit 87d3a6272c

View File

@ -799,8 +799,15 @@ SmiDefaultPFHandler (
for (Index = 0; Index < NumOfPages; Index++) { for (Index = 0; Index < NumOfPages; Index++) {
PageTable = PageTableTop; PageTable = PageTableTop;
UpperEntry = NULL; UpperEntry = NULL;
for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > EndBit; StartBit -= 9) { for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > 12; StartBit -= 9) {
PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8); PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
//
// Iterate through the page table to find the appropriate page table entry for page creation if one of the following cases is met:
// 1) StartBit > EndBit: The PageSize of current entry is bigger than the platform-specified PageSize granularity.
// 2) IA32_PG_P bit is 0 & IA32_PG_PS bit is not 0: The current entry is present and it's a non-leaf entry.
//
if ((StartBit > EndBit) || ((((PageTable[PTIndex] & IA32_PG_P) != 0) && ((PageTable[PTIndex] & IA32_PG_PS) == 0)))) {
if ((PageTable[PTIndex] & IA32_PG_P) == 0) { if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
// //
// If the entry is not present, allocate one page from page pool for it // If the entry is not present, allocate one page from page pool for it
@ -820,6 +827,12 @@ SmiDefaultPFHandler (
PageTable[PTIndex] |= (UINT64)IA32_PG_A; PageTable[PTIndex] |= (UINT64)IA32_PG_A;
SetAccNum (PageTable + PTIndex, 7); SetAccNum (PageTable + PTIndex, 7);
PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask); PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask);
} else {
//
// Found the appropriate entry.
//
break;
}
} }
PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8); PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
@ -827,7 +840,7 @@ SmiDefaultPFHandler (
// //
// Fill the new entry // Fill the new entry
// //
PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << EndBit) - 1)) | PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << StartBit) - 1)) |
PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS; PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS;
if (UpperEntry != NULL) { if (UpperEntry != NULL) {
SetSubEntriesNum (UpperEntry, (GetSubEntriesNum (UpperEntry) + 1) & 0x1FF); SetSubEntriesNum (UpperEntry, (GetSubEntriesNum (UpperEntry) + 1) & 0x1FF);
@ -836,7 +849,7 @@ SmiDefaultPFHandler (
// //
// Get the next page address if we need to create more page tables // Get the next page address if we need to create more page tables
// //
PFAddress += (1ull << EndBit); PFAddress += (1ull << StartBit);
} }
} }