summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
index 556e9f320e..9052ea8e84 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
@@ -799,27 +799,40 @@ SmiDefaultPFHandler (
for (Index = 0; Index < NumOfPages; Index++) {
PageTable = PageTableTop;
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);
- if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
+
+ //
+ // 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 the entry is not present, allocate one page from page pool for it
+ //
+ PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
+ } else {
+ //
+ // Save the upper entry address
+ //
+ UpperEntry = PageTable + PTIndex;
+ }
+
//
- // If the entry is not present, allocate one page from page pool for it
+ // BIT9 to BIT11 of entry is used to save access record,
+ // initialize value is 7
//
- PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
+ PageTable[PTIndex] |= (UINT64)IA32_PG_A;
+ SetAccNum (PageTable + PTIndex, 7);
+ PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask);
} else {
//
- // Save the upper entry address
+ // Found the appropriate entry.
//
- UpperEntry = PageTable + PTIndex;
+ break;
}
-
- //
- // BIT9 to BIT11 of entry is used to save access record,
- // initialize value is 7
- //
- PageTable[PTIndex] |= (UINT64)IA32_PG_A;
- SetAccNum (PageTable + PTIndex, 7);
- PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask);
}
PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
@@ -827,7 +840,7 @@ SmiDefaultPFHandler (
//
// 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;
if (UpperEntry != NULL) {
SetSubEntriesNum (UpperEntry, (GetSubEntriesNum (UpperEntry) + 1) & 0x1FF);
@@ -836,7 +849,7 @@ SmiDefaultPFHandler (
//
// Get the next page address if we need to create more page tables
//
- PFAddress += (1ull << EndBit);
+ PFAddress += (1ull << StartBit);
}
}