diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c index b11264ce4a..5c00c0fa8c 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c @@ -1,7 +1,7 @@ /** @file Page table manipulation functions for IA-32 processors -Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.
+Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -66,6 +66,22 @@ SmmInitPageTable ( return GenSmmPageTable (PagingPae, mPhysicalAddressBits); } +/** + Allocate free Page for PageFault handler use. + + @return Page address. + +**/ +UINT64 +AllocPage ( + VOID + ) +{ + CpuDeadLoop (); + + return 0; +} + /** Page Fault handler for SMM use. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index d54c4c180a..9d8a9dc575 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -1202,6 +1202,21 @@ RestorePageTableBelow4G ( // PDPTE // PTIndex = (UINTN)BitFieldRead64 (PFAddress, 30, 38); + + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { + // + // For 32-bit case, because a full map page table for 0-4G is created by default, + // and since the PDPTE must be one non-leaf entry, the PDPTE must always be present. + // So, ASSERT it must be the 64-bit case running here. + // + ASSERT (sizeof (UINT64) == sizeof (UINTN)); + + // + // If the entry is not present, allocate one page from page pool for it + // + PageTable[PTIndex] = AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS; + } + ASSERT (PageTable[PTIndex] != 0); PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK); @@ -1209,9 +1224,9 @@ RestorePageTableBelow4G ( // PD // PTIndex = (UINTN)BitFieldRead64 (PFAddress, 21, 29); - if ((PageTable[PTIndex] & IA32_PG_PS) != 0) { + if ((PageTable[PTIndex] & IA32_PG_P) == 0) { // - // Large page + // A 2M page size will be used directly when the 2M entry is marked as non-present. // // @@ -1238,7 +1253,8 @@ RestorePageTableBelow4G ( } } else { // - // Small page + // If the 2M entry is marked as present, a 4K page size will be utilized. + // In this scenario, the 2M entry must be a non-leaf entry. // ASSERT (PageTable[PTIndex] != 0); PageTable = (UINT64 *)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK); diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h index 964dd52817..760d76a48d 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h @@ -1,7 +1,7 @@ /** @file SMM profile internal header file. -Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.
Copyright (c) 2020, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -142,6 +142,17 @@ IsAddressValid ( IN BOOLEAN *Nx ); +/** + Allocate free Page for PageFault handler use. + + @return Page address. + +**/ +UINT64 +AllocPage ( + VOID + ); + /** Page Fault handler for SMM use.