27UINT64 *mPFPageUplink[MAX_PF_PAGE_COUNT];
67 ASSERT (Address !=
NULL);
69 mPFPageBuffer = (UINT64)(
UINTN)Address;
71 ZeroMem ((VOID *)(
UINTN)mPFPageBuffer, EFI_PAGE_SIZE * MAX_PF_PAGE_COUNT);
72 ZeroMem (mPFPageUplink,
sizeof (mPFPageUplink));
99 if ((mPFPageUplink[mPFPageIndex] !=
NULL) && ((*mPFPageUplink[mPFPageIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK) == Address)) {
100 *mPFPageUplink[mPFPageIndex] = 0;
106 *Uplink = Address | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
107 mPFPageUplink[mPFPageIndex] = Uplink;
109 mPFPageIndex = (mPFPageIndex + 1) % MAX_PF_PAGE_COUNT;
122 UINT64 *PageTableTop;
133 BOOLEAN Enable5LevelPaging;
139 PageSize = SmmPageSize2M;
144 PageTableTop = (UINT64 *)(
AsmReadCr3 () & gPhyMask);
148 Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 != 0);
155 PageSize = SmmPageSize2M;
160 if (PageSize >= MaxSmmPageSizeType) {
161 PageSize = SmmPageSize2M;
164 if (NumOfPages > 512) {
180 PageAttribute |= (
UINTN)IA32_PG_PS;
183 if (!m1GPageTableSupport) {
184 DEBUG ((DEBUG_ERROR,
"1-GByte pages is not supported!"));
192 PageAttribute |= (
UINTN)IA32_PG_PS;
202 PageAttribute |= IA32_PG_NX;
205 for (Index = 0; Index < NumOfPages; Index++) {
206 PageTable = PageTableTop;
208 for (StartBit = Enable5LevelPaging ? 48 : 39; StartBit > 12; StartBit -= 9) {
216 if ((StartBit > EndBit) || ((((PageTable[PTIndex] & IA32_PG_P) != 0) && ((PageTable[PTIndex] & IA32_PG_PS) == 0)))) {
217 if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
221 PageTable[PTIndex] =
AllocPage () | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
226 UpperEntry = PageTable + PTIndex;
233 PageTable[PTIndex] |= (UINT64)IA32_PG_A;
235 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask & gPhyMask);
249 PageTable[PTIndex] = ((PFAddress | mAddressEncMask) & gPhyMask & ~((1ull << StartBit) - 1)) |
250 PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS;
251 if (UpperEntry !=
NULL) {
258 PFAddress += (1ull << StartBit);
280 BOOLEAN *IsValidPFAddress
290 BOOLEAN Enable5LevelPaging;
292 ASSERT ((PageTable !=
NULL) && (IsValidPFAddress !=
NULL));
295 Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1);
307 PageTable = (UINT64 *)(
AsmReadCr3 () & PHYSICAL_ADDRESS_MASK);
309 if (Enable5LevelPaging) {
313 if ((!Enable5LevelPaging) || ((PageTable[PTIndex] & IA32_PG_P) != 0)) {
315 if (Enable5LevelPaging) {
316 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);
320 if ((PageTable[PTIndex] & IA32_PG_P) != 0) {
322 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);
324 if ((PageTable[PTIndex] & IA32_PG_P) != 0) {
326 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);
329 if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {
333 Address = (UINT64)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);
334 if ((Address & ~((1ull << 21) - 1)) == ((PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)))) {
341 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask& PHYSICAL_ADDRESS_MASK);
342 if (PageTable != 0) {
347 Address = (UINT64)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);
348 if ((Address & ~((1ull << 12) - 1)) == (PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) {
367 *IsValidPFAddress =
TRUE;
377 PageTable = (UINT64 *)(
AsmReadCr3 () & PHYSICAL_ADDRESS_MASK);
380 if (Enable5LevelPaging) {
382 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);
387 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);
390 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);
393 Address = PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK;
401 PageTable = (UINT64 *)(
UINTN)(PageTable[PTIndex] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK);
402 for (Index = 0; Index < 512; Index++) {
403 PageTable[Index] = Address | mAddressEncMask | PAGE_ATTRIBUTE_BITS;
405 PageTable[Index] = PageTable[Index] & (
INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);
408 if (Nx && mXdSupported) {
409 PageTable[Index] = PageTable[Index] | IA32_PG_NX;
412 if (Address == (PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) {
426 PageTable[PTIndex] = PageTable[PTIndex] & (
INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);
432 if (Nx && mXdSupported) {
433 PageTable[PTIndex] = PageTable[PTIndex] | IA32_PG_NX;
443 ASSERT (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT);
444 if (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT) {
445 PFIndex = mPFEntryCount[CpuIndex];
446 mLastPFEntryValue[CpuIndex][PFIndex] = PageTable[PTIndex];
447 mLastPFEntryPointer[CpuIndex][PFIndex] = &PageTable[PTIndex];
448 mPFEntryCount[CpuIndex]++;
454 PageTable[PTIndex] |= (UINT64)(PAGE_ATTRIBUTE_BITS);
455 if ((ErrorCode & IA32_PF_EC_ID) != 0) {
459 PageTable[PTIndex] &= ~IA32_PG_NX;
477 SystemContext.SystemContextX64->Rflags &= (
UINTN) ~BIT8;
UINT64 EFIAPI BitFieldRead64(IN UINT64 Operand, IN UINTN StartBit, IN UINTN EndBit)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINTN EFIAPI AsmReadCr3(VOID)
UINTN EFIAPI AsmReadCr2(VOID)
UINTN EFIAPI AsmReadCr4(VOID)
VOID ClearTrapFlag(IN OUT EFI_SYSTEM_CONTEXT SystemContext)
VOID SmmProfileMapPFAddress(VOID)
VOID InitPagesForPFHandler(VOID)
VOID RestorePageTableAbove4G(UINT64 *PageTable, UINT64 PFAddress, UINTN CpuIndex, UINTN ErrorCode, BOOLEAN *IsValidPFAddress)
VOID InitSmmS3Cr3(OUT UINTN *Cr3)
#define DEBUG(Expression)
UINTN GenSmmPageTable(IN PAGING_MODE PagingMode, IN UINT8 PhysicalAddressBits)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
BOOLEAN IsSmmProfilePFAddressAbove4GValid(IN EFI_PHYSICAL_ADDRESS Address, OUT BOOLEAN *Nx)
BOOLEAN IsAddressSplit(IN EFI_PHYSICAL_ADDRESS Address)
#define EFI_PAGES_TO_SIZE(Pages)
UINT64 GetSubEntriesNum(IN UINT64 *Entry)
VOID SetAccNum(IN OUT UINT64 *Entry, IN UINT64 Acc)
VOID SetSubEntriesNum(IN OUT UINT64 *Entry, IN UINT64 SubEntryNum)
VOID AcquirePage(UINT64 *Uplink)