From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.100, mailfrom: ray.ni@intel.com) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by groups.io with SMTP; Fri, 28 Jun 2019 00:27:53 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Jun 2019 00:27:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,426,1557212400"; d="scan'208";a="156493032" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by orsmga008.jf.intel.com with ESMTP; 28 Jun 2019 00:27:52 -0700 Received: from fmsmsx607.amr.corp.intel.com (10.18.126.87) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 28 Jun 2019 00:27:52 -0700 Received: from fmsmsx607.amr.corp.intel.com (10.18.126.87) by fmsmsx607.amr.corp.intel.com (10.18.126.87) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Fri, 28 Jun 2019 00:27:52 -0700 Received: from shsmsx154.ccr.corp.intel.com (10.239.6.54) by fmsmsx607.amr.corp.intel.com (10.18.126.87) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.1713.5 via Frontend Transport; Fri, 28 Jun 2019 00:27:52 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.185]) by SHSMSX154.ccr.corp.intel.com ([169.254.7.156]) with mapi id 14.03.0439.000; Fri, 28 Jun 2019 15:27:49 +0800 From: "Ni, Ray" To: "Yao, Jiewen" , "devel@edk2.groups.io" CC: "Dong, Eric" Subject: Re: [edk2-devel] [PATCH 3/3] UefiCpuPkg/PiSmmCpu: Enable 5 level paging when CPU supports Thread-Topic: [edk2-devel] [PATCH 3/3] UefiCpuPkg/PiSmmCpu: Enable 5 level paging when CPU supports Thread-Index: AQHVLX1phU4DSTqT5EKSWXouX08iNaawp+ZQgAABRtA= Date: Fri, 28 Jun 2019 07:27:48 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D5C1F4B96@SHSMSX104.ccr.corp.intel.com> References: <20190628064700.549472-1-ray.ni@intel.com> <20190628064700.549472-4-ray.ni@intel.com> <74D8A39837DF1E4DA445A8C0B3885C503F6D34E6@shsmsx102.ccr.corp.intel.com> In-Reply-To: <74D8A39837DF1E4DA445A8C0B3885C503F6D34E6@shsmsx102.ccr.corp.intel.com> Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: ray.ni@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Jiewen, I tested the above 2^48 memory address access in SMM environment to ensure= no GP fault. The code is internally used for a while and this patch is to upstream the = code to edk2 repo. Thanks, Ray > -----Original Message----- > From: Yao, Jiewen > Sent: Friday, June 28, 2019 3:18 PM > To: devel@edk2.groups.io; Ni, Ray > Cc: Dong, Eric > Subject: RE: [edk2-devel] [PATCH 3/3] UefiCpuPkg/PiSmmCpu: Enable 5 leve= l > paging when CPU supports >=20 > Hi > Would you please share the info on what test has been done for this 5 le= vel > paging? >=20 > Such as stack paging enable/disable, SMM profile, etc. >=20 > Thank you > Yao Jiewen >=20 > > -----Original Message----- > > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of > Ni, > > Ray > > Sent: Friday, June 28, 2019 2:47 PM > > To: devel@edk2.groups.io > > Cc: Dong, Eric > > Subject: [edk2-devel] [PATCH 3/3] UefiCpuPkg/PiSmmCpu: Enable 5 level > > paging when CPU supports > > > > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1946 > > > > The patch changes SMM environment to use 5 level paging when CPU > > supports it. > > > > Signed-off-by: Ray Ni > > Cc: Eric Dong > > --- > > .../PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 20 +- > > UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c | 272 ++++++---- > > UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 483 > > ++++++++++++------ > > UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm | 12 + > > .../PiSmmCpuDxeSmm/X64/SmmProfileArch.c | 72 ++- > > 5 files changed, 559 insertions(+), 300 deletions(-) > > > > diff --git > a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > index 069be3aaa5..55090e9c3e 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c > > @@ -125,18 +125,36 @@ GetPageTableEntry ( > > UINTN Index2; > > UINTN Index3; > > UINTN Index4; > > + UINTN Index5; > > UINT64 *L1PageTable; > > UINT64 *L2PageTable; > > UINT64 *L3PageTable; > > UINT64 *L4PageTable; > > + UINT64 *L5PageTable; > > + IA32_CR4 Cr4; > > + BOOLEAN Enable5LevelPaging; > > > > + Index5 =3D ((UINTN)RShiftU64 (Address, 48)) & > PAGING_PAE_INDEX_MASK; > > Index4 =3D ((UINTN)RShiftU64 (Address, 39)) & > PAGING_PAE_INDEX_MASK; > > Index3 =3D ((UINTN)Address >> 30) & PAGING_PAE_INDEX_MASK; > > Index2 =3D ((UINTN)Address >> 21) & PAGING_PAE_INDEX_MASK; > > Index1 =3D ((UINTN)Address >> 12) & PAGING_PAE_INDEX_MASK; > > > > + Cr4.UintN =3D AsmReadCr4 (); > > + Enable5LevelPaging =3D (BOOLEAN) (Cr4.Bits.LA57 =3D=3D 1); > > + > > if (sizeof(UINTN) =3D=3D sizeof(UINT64)) { > > - L4PageTable =3D (UINT64 *)GetPageTableBase (); > > + if (Enable5LevelPaging) { > > + L5PageTable =3D (UINT64 *)GetPageTableBase (); > > + if (L5PageTable[Index5] =3D=3D 0) { > > + *PageAttribute =3D PageNone; > > + return NULL; > > + } > > + > > + L4PageTable =3D (UINT64 *)(UINTN)(L5PageTable[Index5] & > > ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > + } else { > > + L4PageTable =3D (UINT64 *)GetPageTableBase (); > > + } > > if (L4PageTable[Index4] =3D=3D 0) { > > *PageAttribute =3D PageNone; > > return NULL; > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c > > b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c > > index e2b6a2d9b2..c5131526f0 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c > > @@ -534,43 +534,78 @@ InitPaging ( > > VOID > > ) > > { > > + UINT64 Pml5Entry; > > + UINT64 Pml4Entry; > > + UINT64 *Pml5; > > UINT64 *Pml4; > > UINT64 *Pdpt; > > UINT64 *Pd; > > UINT64 *Pt; > > UINTN Address; > > + UINTN Pml5Index; > > UINTN Pml4Index; > > UINTN PdptIndex; > > UINTN PdIndex; > > UINTN PtIndex; > > UINTN NumberOfPdptEntries; > > UINTN NumberOfPml4Entries; > > + UINTN NumberOfPml5Entries; > > UINTN SizeOfMemorySpace; > > BOOLEAN Nx; > > + IA32_CR4 Cr4; > > + BOOLEAN Enable5LevelPaging; > > + > > + Cr4.UintN =3D AsmReadCr4 (); > > + Enable5LevelPaging =3D (BOOLEAN) (Cr4.Bits.LA57 =3D=3D 1); > > > > if (sizeof (UINTN) =3D=3D sizeof (UINT64)) { > > - Pml4 =3D (UINT64*)(UINTN)mSmmProfileCr3; > > + if (!Enable5LevelPaging) { > > + Pml5Entry =3D (UINTN) mSmmProfileCr3 | IA32_PG_P; > > + Pml5 =3D &Pml5Entry; > > + } else { > > + Pml5 =3D (UINT64*) (UINTN) mSmmProfileCr3; > > + } > > SizeOfMemorySpace =3D HighBitSet64 (gPhyMask) + 1; > > // > > // Calculate the table entries of PML4E and PDPTE. > > // > > - if (SizeOfMemorySpace <=3D 39 ) { > > - NumberOfPml4Entries =3D 1; > > - NumberOfPdptEntries =3D (UINT32)LShiftU64 (1, (SizeOfMemorySpac= e > > - 30)); > > - } else { > > - NumberOfPml4Entries =3D (UINT32)LShiftU64 (1, (SizeOfMemorySpac= e > > - 39)); > > - NumberOfPdptEntries =3D 512; > > + NumberOfPml5Entries =3D 1; > > + if (SizeOfMemorySpace > 48) { > > + NumberOfPml5Entries =3D (UINTN) LShiftU64 (1, SizeOfMemorySpace > > - 48); > > + SizeOfMemorySpace =3D 48; > > } > > - } else { > > + > > NumberOfPml4Entries =3D 1; > > + if (SizeOfMemorySpace > 39) { > > + NumberOfPml4Entries =3D (UINTN) LShiftU64 (1, SizeOfMemorySpace > > - 39); > > + SizeOfMemorySpace =3D 39; > > + } > > + > > + NumberOfPdptEntries =3D 1; > > + ASSERT (SizeOfMemorySpace > 30); > > + NumberOfPdptEntries =3D (UINTN) LShiftU64 (1, SizeOfMemorySpace - > > 30); > > + } else { > > + Pml4Entry =3D (UINTN) mSmmProfileCr3 | IA32_PG_P; > > + Pml4 =3D &Pml4Entry; > > + Pml5Entry =3D (UINTN) Pml4 | IA32_PG_P; > > + Pml5 =3D &Pml5Entry; > > + NumberOfPml5Entries =3D 1; > > + NumberOfPml4Entries =3D 1; > > NumberOfPdptEntries =3D 4; > > } > > > > // > > // Go through page table and change 2MB-page into 4KB-page. > > // > > - for (Pml4Index =3D 0; Pml4Index < NumberOfPml4Entries; Pml4Index++)= { > > - if (sizeof (UINTN) =3D=3D sizeof (UINT64)) { > > + for (Pml5Index =3D 0; Pml5Index < NumberOfPml5Entries; Pml5Index++)= { > > + if ((Pml5[Pml5Index] & IA32_PG_P) =3D=3D 0) { > > + // > > + // If PML5 entry does not exist, skip it > > + // > > + continue; > > + } > > + Pml4 =3D (UINT64 *) (UINTN) (Pml5[Pml5Index] & > > PHYSICAL_ADDRESS_MASK); > > + for (Pml4Index =3D 0; Pml4Index < NumberOfPml4Entries; Pml4Index+= +) { > > if ((Pml4[Pml4Index] & IA32_PG_P) =3D=3D 0) { > > // > > // If PML4 entry does not exist, skip it > > @@ -578,63 +613,76 @@ InitPaging ( > > continue; > > } > > Pdpt =3D (UINT64 *)(UINTN)(Pml4[Pml4Index] & ~mAddressEncMask > > & PHYSICAL_ADDRESS_MASK); > > - } else { > > - Pdpt =3D (UINT64*)(UINTN)mSmmProfileCr3; > > - } > > - for (PdptIndex =3D 0; PdptIndex < NumberOfPdptEntries; PdptIndex+= +, > > Pdpt++) { > > - if ((*Pdpt & IA32_PG_P) =3D=3D 0) { > > - // > > - // If PDPT entry does not exist, skip it > > - // > > - continue; > > - } > > - if ((*Pdpt & IA32_PG_PS) !=3D 0) { > > - // > > - // This is 1G entry, skip it > > - // > > - continue; > > - } > > - Pd =3D (UINT64 *)(UINTN)(*Pdpt & ~mAddressEncMask & > > PHYSICAL_ADDRESS_MASK); > > - if (Pd =3D=3D 0) { > > - continue; > > - } > > - for (PdIndex =3D 0; PdIndex < SIZE_4KB / sizeof (*Pd); PdIndex+= +, Pd++) > > { > > - if ((*Pd & IA32_PG_P) =3D=3D 0) { > > + for (PdptIndex =3D 0; PdptIndex < NumberOfPdptEntries; PdptInde= x++, > > Pdpt++) { > > + if ((*Pdpt & IA32_PG_P) =3D=3D 0) { > > + // > > + // If PDPT entry does not exist, skip it > > + // > > + continue; > > + } > > + if ((*Pdpt & IA32_PG_PS) !=3D 0) { > > // > > - // If PD entry does not exist, skip it > > + // This is 1G entry, skip it > > // > > continue; > > } > > - Address =3D (((PdptIndex << 9) + PdIndex) << 21); > > + Pd =3D (UINT64 *)(UINTN)(*Pdpt & ~mAddressEncMask & > > PHYSICAL_ADDRESS_MASK); > > + if (Pd =3D=3D 0) { > > + continue; > > + } > > + for (PdIndex =3D 0; PdIndex < SIZE_4KB / sizeof (*Pd); PdInde= x++, > > Pd++) { > > + if ((*Pd & IA32_PG_P) =3D=3D 0) { > > + // > > + // If PD entry does not exist, skip it > > + // > > + continue; > > + } > > + Address =3D (UINTN) LShiftU64 ( > > + LShiftU64 ( > > + LShiftU64 ((Pml5Index << 9) + > > Pml4Index, 9) + PdptIndex, > > + 9 > > + ) + PdIndex, > > + 21 > > + ); > > > > - // > > - // If it is 2M page, check IsAddressSplit() > > - // > > - if (((*Pd & IA32_PG_PS) !=3D 0) && IsAddressSplit (Address)) = { > > // > > - // Based on current page table, create 4KB page table for s= plit > > area. > > + // If it is 2M page, check IsAddressSplit() > > // > > - ASSERT (Address =3D=3D (*Pd & PHYSICAL_ADDRESS_MASK)); > > + if (((*Pd & IA32_PG_PS) !=3D 0) && IsAddressSplit (Address)= ) { > > + // > > + // Based on current page table, create 4KB page table for > > split area. > > + // > > + ASSERT (Address =3D=3D (*Pd & PHYSICAL_ADDRESS_MASK)); > > + > > + Pt =3D AllocatePageTableMemory (1); > > + ASSERT (Pt !=3D NULL); > > > > - Pt =3D AllocatePageTableMemory (1); > > - ASSERT (Pt !=3D NULL); > > + *Pd =3D (UINTN) Pt | IA32_PG_RW | IA32_PG_P; > > > > - // Split it > > - for (PtIndex =3D 0; PtIndex < SIZE_4KB / sizeof(*Pt); PtInd= ex++) { > > - Pt[PtIndex] =3D Address + ((PtIndex << 12) | mAddressEncM= ask > > | PAGE_ATTRIBUTE_BITS); > > - } // end for PT > > - *Pd =3D (UINT64)(UINTN)Pt | mAddressEncMask | > > PAGE_ATTRIBUTE_BITS; > > - } // end if IsAddressSplit > > - } // end for PD > > - } // end for PDPT > > - } // end for PML4 > > + // Split it > > + for (PtIndex =3D 0; PtIndex < SIZE_4KB / sizeof(*Pt); PtI= ndex++, > > Pt++) { > > + *Pt =3D Address + ((PtIndex << 12) | mAddressEncMask | > > PAGE_ATTRIBUTE_BITS); > > + } // end for PT > > + *Pd =3D (UINT64)(UINTN)Pt | mAddressEncMask | > > PAGE_ATTRIBUTE_BITS; > > + } // end if IsAddressSplit > > + } // end for PD > > + } // end for PDPT > > + } // end for PML4 > > + } // end for PML5 > > > > // > > // Go through page table and set several page table entries to abse= nt or > > execute-disable. > > // > > DEBUG ((EFI_D_INFO, "Patch page table start ...\n")); > > - for (Pml4Index =3D 0; Pml4Index < NumberOfPml4Entries; Pml4Index++)= { > > - if (sizeof (UINTN) =3D=3D sizeof (UINT64)) { > > + for (Pml5Index =3D 0; Pml5Index < NumberOfPml5Entries; Pml5Index++)= { > > + if ((Pml5[Pml5Index] & IA32_PG_P) =3D=3D 0) { > > + // > > + // If PML5 entry does not exist, skip it > > + // > > + continue; > > + } > > + Pml4 =3D (UINT64 *) (UINTN) (Pml5[Pml5Index] & > > PHYSICAL_ADDRESS_MASK); > > + for (Pml4Index =3D 0; Pml4Index < NumberOfPml4Entries; Pml4Index+= +) { > > if ((Pml4[Pml4Index] & IA32_PG_P) =3D=3D 0) { > > // > > // If PML4 entry does not exist, skip it > > @@ -642,69 +690,73 @@ InitPaging ( > > continue; > > } > > Pdpt =3D (UINT64 *)(UINTN)(Pml4[Pml4Index] & ~mAddressEncMask > > & PHYSICAL_ADDRESS_MASK); > > - } else { > > - Pdpt =3D (UINT64*)(UINTN)mSmmProfileCr3; > > - } > > - for (PdptIndex =3D 0; PdptIndex < NumberOfPdptEntries; PdptIndex+= +, > > Pdpt++) { > > - if ((*Pdpt & IA32_PG_P) =3D=3D 0) { > > - // > > - // If PDPT entry does not exist, skip it > > - // > > - continue; > > - } > > - if ((*Pdpt & IA32_PG_PS) !=3D 0) { > > - // > > - // This is 1G entry, set NX bit and skip it > > - // > > - if (mXdSupported) { > > - *Pdpt =3D *Pdpt | IA32_PG_NX; > > + for (PdptIndex =3D 0; PdptIndex < NumberOfPdptEntries; PdptInde= x++, > > Pdpt++) { > > + if ((*Pdpt & IA32_PG_P) =3D=3D 0) { > > + // > > + // If PDPT entry does not exist, skip it > > + // > > + continue; > > } > > - continue; > > - } > > - Pd =3D (UINT64 *)(UINTN)(*Pdpt & ~mAddressEncMask & > > PHYSICAL_ADDRESS_MASK); > > - if (Pd =3D=3D 0) { > > - continue; > > - } > > - for (PdIndex =3D 0; PdIndex < SIZE_4KB / sizeof (*Pd); PdIndex+= +, Pd++) > > { > > - if ((*Pd & IA32_PG_P) =3D=3D 0) { > > + if ((*Pdpt & IA32_PG_PS) !=3D 0) { > > // > > - // If PD entry does not exist, skip it > > + // This is 1G entry, set NX bit and skip it > > // > > + if (mXdSupported) { > > + *Pdpt =3D *Pdpt | IA32_PG_NX; > > + } > > continue; > > } > > - Address =3D (((PdptIndex << 9) + PdIndex) << 21); > > - > > - if ((*Pd & IA32_PG_PS) !=3D 0) { > > - // 2MB page > > - > > - if (!IsAddressValid (Address, &Nx)) { > > + Pd =3D (UINT64 *)(UINTN)(*Pdpt & ~mAddressEncMask & > > PHYSICAL_ADDRESS_MASK); > > + if (Pd =3D=3D 0) { > > + continue; > > + } > > + for (PdIndex =3D 0; PdIndex < SIZE_4KB / sizeof (*Pd); PdInde= x++, > > Pd++) { > > + if ((*Pd & IA32_PG_P) =3D=3D 0) { > > // > > - // Patch to remove Present flag and RW flag > > + // If PD entry does not exist, skip it > > // > > - *Pd =3D *Pd & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); > > - } > > - if (Nx && mXdSupported) { > > - *Pd =3D *Pd | IA32_PG_NX; > > - } > > - } else { > > - // 4KB page > > - Pt =3D (UINT64 *)(UINTN)(*Pd & ~mAddressEncMask & > > PHYSICAL_ADDRESS_MASK); > > - if (Pt =3D=3D 0) { > > continue; > > } > > - for (PtIndex =3D 0; PtIndex < SIZE_4KB / sizeof(*Pt); PtInd= ex++, > > Pt++) { > > + Address =3D (UINTN) LShiftU64 ( > > + LShiftU64 ( > > + LShiftU64 ((Pml5Index << 9) + > > Pml4Index, 9) + PdptIndex, > > + 9 > > + ) + PdIndex, > > + 21 > > + ); > > + > > + if ((*Pd & IA32_PG_PS) !=3D 0) { > > + // 2MB page > > + > > if (!IsAddressValid (Address, &Nx)) { > > - *Pt =3D *Pt & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); > > + // > > + // Patch to remove Present flag and RW flag > > + // > > + *Pd =3D *Pd & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); > > } > > if (Nx && mXdSupported) { > > - *Pt =3D *Pt | IA32_PG_NX; > > + *Pd =3D *Pd | IA32_PG_NX; > > + } > > + } else { > > + // 4KB page > > + Pt =3D (UINT64 *)(UINTN)(*Pd & ~mAddressEncMask & > > PHYSICAL_ADDRESS_MASK); > > + if (Pt =3D=3D 0) { > > + continue; > > } > > - Address +=3D SIZE_4KB; > > - } // end for PT > > - } // end if PS > > - } // end for PD > > - } // end for PDPT > > - } // end for PML4 > > + for (PtIndex =3D 0; PtIndex < SIZE_4KB / sizeof(*Pt); PtI= ndex++, > > Pt++) { > > + if (!IsAddressValid (Address, &Nx)) { > > + *Pt =3D *Pt & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); > > + } > > + if (Nx && mXdSupported) { > > + *Pt =3D *Pt | IA32_PG_NX; > > + } > > + Address +=3D SIZE_4KB; > > + } // end for PT > > + } // end if PS > > + } // end for PD > > + } // end for PDPT > > + } // end for PML4 > > + } // end for PML5 > > > > // > > // Flush TLB > > @@ -1156,6 +1208,20 @@ RestorePageTableBelow4G ( > > { > > UINTN PTIndex; > > UINTN PFIndex; > > + IA32_CR4 Cr4; > > + BOOLEAN Enable5LevelPaging; > > + > > + Cr4.UintN =3D AsmReadCr4 (); > > + Enable5LevelPaging =3D (BOOLEAN) (Cr4.Bits.LA57 =3D=3D 1); > > + > > + // > > + // PML5 > > + // > > + if (Enable5LevelPaging) { > > + PTIndex =3D (UINTN)BitFieldRead64 (PFAddress, 48, 56); > > + ASSERT (PageTable[PTIndex] !=3D 0); > > + PageTable =3D (UINT64*)(UINTN)(PageTable[PTIndex] & > > PHYSICAL_ADDRESS_MASK); > > + } > > > > // > > // PML4 > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > index 3d5d663d99..c088010327 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c > > @@ -16,6 +16,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > > LIST_ENTRY mPagePool =3D > > INITIALIZE_LIST_HEAD_VARIABLE (mPagePool); > > BOOLEAN m1GPageTableSupport =3D > > FALSE; > > BOOLEAN mCpuSmmStaticPageTable; > > +BOOLEAN m5LevelPagingSupport; > > > > /** > > Disable CET. > > @@ -60,6 +61,31 @@ Is1GPageSupport ( > > return FALSE; > > } > > > > +/** > > + Check if 5-level paging is supported by processor or not. > > + > > + @retval TRUE 5-level paging is supported. > > + @retval FALSE 5-level paging is not supported. > > + > > +**/ > > +BOOLEAN > > +Is5LevelPagingSupport ( > > + VOID > > + ) > > +{ > > + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX EcxFlags; > > + > > + AsmCpuidEx ( > > + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, > > + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, > > + NULL, > > + NULL, > > + &EcxFlags.Uint32, > > + NULL > > + ); > > + return (BOOLEAN) (EcxFlags.Bits.FiveLevelPage !=3D 0); > > +} > > + > > /** > > Set sub-entries number in entry. > > > > @@ -130,14 +156,6 @@ CalculateMaximumSupportAddress ( > > PhysicalAddressBits =3D 36; > > } > > } > > - > > - // > > - // IA-32e paging translates 48-bit linear addresses to 52-bit physi= cal > > addresses. > > - // > > - ASSERT (PhysicalAddressBits <=3D 52); > > - if (PhysicalAddressBits > 48) { > > - PhysicalAddressBits =3D 48; > > - } > > return PhysicalAddressBits; > > } > > > > @@ -152,89 +170,137 @@ SetStaticPageTable ( > > ) > > { > > UINT64 PageAddress; > > + UINTN > > NumberOfPml5EntriesNeeded; > > UINTN > > NumberOfPml4EntriesNeeded; > > UINTN > > NumberOfPdpEntriesNeeded; > > + UINTN > > IndexOfPml5Entries; > > UINTN > > IndexOfPml4Entries; > > UINTN > > IndexOfPdpEntries; > > UINTN > > IndexOfPageDirectoryEntries; > > + UINT64 > > *PageMapLevel5Entry; > > UINT64 > > *PageMapLevel4Entry; > > UINT64 *PageMap; > > UINT64 > > *PageDirectoryPointerEntry; > > UINT64 > > *PageDirectory1GEntry; > > UINT64 > > *PageDirectoryEntry; > > > > - if (mPhysicalAddressBits <=3D 39 ) { > > - NumberOfPml4EntriesNeeded =3D 1; > > - NumberOfPdpEntriesNeeded =3D (UINT32)LShiftU64 (1, > > (mPhysicalAddressBits - 30)); > > - } else { > > - NumberOfPml4EntriesNeeded =3D (UINT32)LShiftU64 (1, > > (mPhysicalAddressBits - 39)); > > - NumberOfPdpEntriesNeeded =3D 512; > > + // > > + // IA-32e paging translates 48-bit linear addresses to 52-bit physi= cal > > addresses > > + // when 5-Level Paging is disabled. > > + // > > + ASSERT (mPhysicalAddressBits <=3D 52); > > + if (!m5LevelPagingSupport && mPhysicalAddressBits > 48) { > > + mPhysicalAddressBits =3D 48; > > + } > > + > > + NumberOfPml5EntriesNeeded =3D 1; > > + if (mPhysicalAddressBits > 48) { > > + NumberOfPml5EntriesNeeded =3D (UINTN) LShiftU64 (1, > > mPhysicalAddressBits - 48); > > + mPhysicalAddressBits =3D 48; > > + } > > + > > + NumberOfPml4EntriesNeeded =3D 1; > > + if (mPhysicalAddressBits > 39) { > > + NumberOfPml4EntriesNeeded =3D (UINTN) LShiftU64 (1, > > mPhysicalAddressBits - 39); > > + mPhysicalAddressBits =3D 39; > > } > > > > + NumberOfPdpEntriesNeeded =3D 1; > > + ASSERT (mPhysicalAddressBits > 30); > > + NumberOfPdpEntriesNeeded =3D (UINTN) LShiftU64 (1, > > mPhysicalAddressBits - 30); > > + > > // > > // By architecture only one PageMapLevel4 exists - so lets allocate > > storage for it. > > // > > PageMap =3D (VOID *) PageTable; > > > > PageMapLevel4Entry =3D PageMap; > > - PageAddress =3D 0; > > - for (IndexOfPml4Entries =3D 0; IndexOfPml4Entries < > > NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, > > PageMapLevel4Entry++) { > > + PageMapLevel5Entry =3D NULL; > > + if (m5LevelPagingSupport) { > > // > > - // Each PML4 entry points to a page of Page Directory Pointer ent= ries. > > + // By architecture only one PageMapLevel5 exists - so lets alloca= te > > storage for it. > > // > > - PageDirectoryPointerEntry =3D (UINT64 *) ((*PageMapLevel4Entry) & > > ~mAddressEncMask & gPhyMask); > > - if (PageDirectoryPointerEntry =3D=3D NULL) { > > - PageDirectoryPointerEntry =3D AllocatePageTableMemory (1); > > - ASSERT(PageDirectoryPointerEntry !=3D NULL); > > - ZeroMem (PageDirectoryPointerEntry, EFI_PAGES_TO_SIZE(1)); > > + PageMapLevel5Entry =3D PageMap; > > + } > > + PageAddress =3D 0; > > > > - *PageMapLevel4Entry =3D (UINT64)(UINTN)PageDirectoryPointerEntr= y > > | mAddressEncMask | PAGE_ATTRIBUTE_BITS; > > + for ( IndexOfPml5Entries =3D 0 > > + ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded > > + ; IndexOfPml5Entries++, PageMapLevel5Entry++) { > > + // > > + // Each PML5 entry points to a page of PML4 entires. > > + // So lets allocate space for them and fill them in in the > > IndexOfPml4Entries loop. > > + // When 5-Level Paging is disabled, below allocation happens only > > once. > > + // > > + if (m5LevelPagingSupport) { > > + PageMapLevel4Entry =3D (UINT64 *) ((*PageMapLevel5Entry) & > > ~mAddressEncMask & gPhyMask); > > + if (PageMapLevel4Entry =3D=3D NULL) { > > + PageMapLevel4Entry =3D AllocatePageTableMemory (1); > > + ASSERT(PageMapLevel4Entry !=3D NULL); > > + ZeroMem (PageMapLevel4Entry, EFI_PAGES_TO_SIZE(1)); > > + > > + *PageMapLevel5Entry =3D (UINT64)(UINTN)PageMapLevel4Entry | > > mAddressEncMask | PAGE_ATTRIBUTE_BITS; > > + } > > } > > > > - if (m1GPageTableSupport) { > > - PageDirectory1GEntry =3D PageDirectoryPointerEntry; > > - for (IndexOfPageDirectoryEntries =3D 0; IndexOfPageDirectoryEnt= ries > > < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, > > PageAddress +=3D SIZE_1GB) { > > - if (IndexOfPml4Entries =3D=3D 0 && IndexOfPageDirectoryEntrie= s < 4) { > > - // > > - // Skip the < 4G entries > > - // > > - continue; > > - } > > - // > > - // Fill in the Page Directory entries > > - // > > - *PageDirectory1GEntry =3D PageAddress | mAddressEncMask | > > IA32_PG_PS | PAGE_ATTRIBUTE_BITS; > > + for (IndexOfPml4Entries =3D 0; IndexOfPml4Entries < > > (NumberOfPml5EntriesNeeded =3D=3D 1 ? NumberOfPml4EntriesNeeded : 512)= ; > > IndexOfPml4Entries++, PageMapLevel4Entry++) { > > + // > > + // Each PML4 entry points to a page of Page Directory Pointer > > entries. > > + // > > + PageDirectoryPointerEntry =3D (UINT64 *) ((*PageMapLevel4Entry)= & > > ~mAddressEncMask & gPhyMask); > > + if (PageDirectoryPointerEntry =3D=3D NULL) { > > + PageDirectoryPointerEntry =3D AllocatePageTableMemory (1); > > + ASSERT(PageDirectoryPointerEntry !=3D NULL); > > + ZeroMem (PageDirectoryPointerEntry, EFI_PAGES_TO_SIZE(1)); > > + > > + *PageMapLevel4Entry =3D > > (UINT64)(UINTN)PageDirectoryPointerEntry | mAddressEncMask | > > PAGE_ATTRIBUTE_BITS; > > } > > - } else { > > - PageAddress =3D BASE_4GB; > > - for (IndexOfPdpEntries =3D 0; IndexOfPdpEntries < > > NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, > > PageDirectoryPointerEntry++) { > > - if (IndexOfPml4Entries =3D=3D 0 && IndexOfPdpEntries < 4) { > > - // > > - // Skip the < 4G entries > > - // > > - continue; > > - } > > - // > > - // Each Directory Pointer entries points to a page of Page > > Directory entires. > > - // So allocate space for them and fill them in in the > > IndexOfPageDirectoryEntries loop. > > - // > > - PageDirectoryEntry =3D (UINT64 *) ((*PageDirectoryPointerEntr= y) & > > ~mAddressEncMask & gPhyMask); > > - if (PageDirectoryEntry =3D=3D NULL) { > > - PageDirectoryEntry =3D AllocatePageTableMemory (1); > > - ASSERT(PageDirectoryEntry !=3D NULL); > > - ZeroMem (PageDirectoryEntry, EFI_PAGES_TO_SIZE(1)); > > > > + if (m1GPageTableSupport) { > > + PageDirectory1GEntry =3D PageDirectoryPointerEntry; > > + for (IndexOfPageDirectoryEntries =3D 0; > > IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, > > PageDirectory1GEntry++, PageAddress +=3D SIZE_1GB) { > > + if (IndexOfPml4Entries =3D=3D 0 && IndexOfPageDirectoryEntr= ies < > > 4) { > > + // > > + // Skip the < 4G entries > > + // > > + continue; > > + } > > // > > - // Fill in a Page Directory Pointer Entries > > + // Fill in the Page Directory entries > > // > > - *PageDirectoryPointerEntry =3D > > (UINT64)(UINTN)PageDirectoryEntry | mAddressEncMask | > > PAGE_ATTRIBUTE_BITS; > > + *PageDirectory1GEntry =3D PageAddress | mAddressEncMask | > > IA32_PG_PS | PAGE_ATTRIBUTE_BITS; > > } > > - > > - for (IndexOfPageDirectoryEntries =3D 0; > > IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, > > PageDirectoryEntry++, PageAddress +=3D SIZE_2MB) { > > + } else { > > + PageAddress =3D BASE_4GB; > > + for (IndexOfPdpEntries =3D 0; IndexOfPdpEntries < > > (NumberOfPml4EntriesNeeded =3D=3D 1 ? NumberOfPdpEntriesNeeded : 512); > > IndexOfPdpEntries++, PageDirectoryPointerEntry++) { > > + if (IndexOfPml4Entries =3D=3D 0 && IndexOfPdpEntries < 4) { > > + // > > + // Skip the < 4G entries > > + // > > + continue; > > + } > > // > > - // Fill in the Page Directory entries > > + // Each Directory Pointer entries points to a page of Page > > Directory entires. > > + // So allocate space for them and fill them in in the > > IndexOfPageDirectoryEntries loop. > > // > > - *PageDirectoryEntry =3D PageAddress | mAddressEncMask | > > IA32_PG_PS | PAGE_ATTRIBUTE_BITS; > > + PageDirectoryEntry =3D (UINT64 *) ((*PageDirectoryPointerEn= try) > > & ~mAddressEncMask & gPhyMask); > > + if (PageDirectoryEntry =3D=3D NULL) { > > + PageDirectoryEntry =3D AllocatePageTableMemory (1); > > + ASSERT(PageDirectoryEntry !=3D NULL); > > + ZeroMem (PageDirectoryEntry, EFI_PAGES_TO_SIZE(1)); > > + > > + // > > + // Fill in a Page Directory Pointer Entries > > + // > > + *PageDirectoryPointerEntry =3D > > (UINT64)(UINTN)PageDirectoryEntry | mAddressEncMask | > > PAGE_ATTRIBUTE_BITS; > > + } > > + > > + for (IndexOfPageDirectoryEntries =3D 0; > > IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, > > PageDirectoryEntry++, PageAddress +=3D SIZE_2MB) { > > + // > > + // Fill in the Page Directory entries > > + // > > + *PageDirectoryEntry =3D PageAddress | mAddressEncMask | > > IA32_PG_PS | PAGE_ATTRIBUTE_BITS; > > + } > > } > > } > > } > > @@ -259,6 +325,8 @@ SmmInitPageTable ( > > UINTN > > PageFaultHandlerHookAddress; > > IA32_IDT_GATE_DESCRIPTOR *IdtEntry; > > EFI_STATUS Status; > > + UINT64 *Pml4Entry; > > + UINT64 *Pml5Entry; > > > > // > > // Initialize spin lock > > @@ -266,12 +334,13 @@ SmmInitPageTable ( > > InitializeSpinLock (mPFLock); > > > > mCpuSmmStaticPageTable =3D PcdGetBool (PcdCpuSmmStaticPageTable); > > - m1GPageTableSupport =3D Is1GPageSupport (); > > - DEBUG ((DEBUG_INFO, "1GPageTableSupport - 0x%x\n", > > m1GPageTableSupport)); > > - DEBUG ((DEBUG_INFO, "PcdCpuSmmStaticPageTable - 0x%x\n", > > mCpuSmmStaticPageTable)); > > - > > - mPhysicalAddressBits =3D CalculateMaximumSupportAddress (); > > - DEBUG ((DEBUG_INFO, "PhysicalAddressBits - 0x%x\n", > > mPhysicalAddressBits)); > > + m1GPageTableSupport =3D Is1GPageSupport (); > > + m5LevelPagingSupport =3D Is5LevelPagingSupport (); > > + mPhysicalAddressBits =3D CalculateMaximumSupportAddress (); > > + DEBUG ((DEBUG_INFO, "5LevelPaging Support - %d\n", > > m5LevelPagingSupport)); > > + DEBUG ((DEBUG_INFO, "1GPageTable Support - %d\n", > > m1GPageTableSupport)); > > + DEBUG ((DEBUG_INFO, "PcdCpuSmmStaticPageTable - %d\n", > > mCpuSmmStaticPageTable)); > > + DEBUG ((DEBUG_INFO, "PhysicalAddressBits - %d\n", > > mPhysicalAddressBits)); > > // > > // Generate PAE page table for the first 4GB memory space > > // > > @@ -288,15 +357,30 @@ SmmInitPageTable ( > > // > > // Fill Page-Table-Level4 (PML4) entry > > // > > - PTEntry =3D (UINT64*)AllocatePageTableMemory (1); > > - ASSERT (PTEntry !=3D NULL); > > - *PTEntry =3D Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS; > > - ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry)); > > + Pml4Entry =3D (UINT64*)AllocatePageTableMemory (1); > > + ASSERT (Pml4Entry !=3D NULL); > > + *Pml4Entry =3D Pages | mAddressEncMask | PAGE_ATTRIBUTE_BITS; > > + ZeroMem (Pml4Entry + 1, EFI_PAGE_SIZE - sizeof (*Pml4Entry)); > > > > // > > // Set sub-entries number > > // > > - SetSubEntriesNum (PTEntry, 3); > > + SetSubEntriesNum (Pml4Entry, 3); > > + PTEntry =3D Pml4Entry; > > + > > + if (m5LevelPagingSupport) { > > + // > > + // Fill PML5 entry > > + // > > + Pml5Entry =3D (UINT64*)AllocatePageTableMemory (1); > > + *Pml5Entry =3D (UINTN) Pml4Entry | mAddressEncMask | > > PAGE_ATTRIBUTE_BITS; > > + ZeroMem (Pml5Entry + 1, EFI_PAGE_SIZE - sizeof (*Pml5Entry)); > > + // > > + // Set sub-entries number > > + // > > + SetSubEntriesNum (Pml5Entry, 1); > > + PTEntry =3D Pml5Entry; > > + } > > > > if (mCpuSmmStaticPageTable) { > > SetStaticPageTable ((UINTN)PTEntry); > > @@ -344,7 +428,7 @@ SmmInitPageTable ( > > } > > > > // > > - // Return the address of PML4 (to set CR3) > > + // Return the address of PML4/PML5 (to set CR3) > > // > > return (UINT32)(UINTN)PTEntry; > > } > > @@ -436,12 +520,16 @@ ReclaimPages ( > > VOID > > ) > > { > > + UINT64 Pml5Entry; > > + UINT64 *Pml5; > > UINT64 *Pml4; > > UINT64 *Pdpt; > > UINT64 *Pdt; > > + UINTN Pml5Index; > > UINTN Pml4Index; > > UINTN PdptIndex; > > UINTN PdtIndex; > > + UINTN MinPml5; > > UINTN MinPml4; > > UINTN MinPdpt; > > UINTN MinPdt; > > @@ -451,120 +539,147 @@ ReclaimPages ( > > BOOLEAN PML4EIgnore; > > BOOLEAN PDPTEIgnore; > > UINT64 *ReleasePageAddress; > > + IA32_CR4 Cr4; > > + BOOLEAN Enable5LevelPaging; > > > > Pml4 =3D NULL; > > Pdpt =3D NULL; > > Pdt =3D NULL; > > MinAcc =3D (UINT64)-1; > > MinPml4 =3D (UINTN)-1; > > + MinPml5 =3D (UINTN)-1; > > MinPdpt =3D (UINTN)-1; > > MinPdt =3D (UINTN)-1; > > Acc =3D 0; > > ReleasePageAddress =3D 0; > > > > + Cr4.UintN =3D AsmReadCr4 (); > > + Enable5LevelPaging =3D (BOOLEAN) (Cr4.Bits.LA57 =3D=3D 1); > > + Pml5 =3D (UINT64*)(UINTN)(AsmReadCr3 () & gPhyMask); > > + > > + if (!Enable5LevelPaging) { > > + // > > + // Create one fake PML5 entry for 4-Level Paging > > + // so that the page table parsing logic only handles 5-Level page > > structure. > > + // > > + Pml5Entry =3D (UINTN) Pml5 | IA32_PG_P; > > + Pml5 =3D &Pml5Entry; > > + } > > + > > // > > // First, find the leaf entry has the smallest access record value > > // > > - Pml4 =3D (UINT64*)(UINTN)(AsmReadCr3 () & gPhyMask); > > - for (Pml4Index =3D 0; Pml4Index < EFI_PAGE_SIZE / sizeof (*Pml4); > > Pml4Index++) { > > - if ((Pml4[Pml4Index] & IA32_PG_P) =3D=3D 0 || (Pml4[Pml4Index] & > > IA32_PG_PMNT) !=3D 0) { > > + for (Pml5Index =3D 0; Pml5Index < Enable5LevelPaging ? (EFI_PAGE_SI= ZE / > > sizeof (*Pml4)) : 1; Pml5Index++) { > > + if ((Pml5[Pml5Index] & IA32_PG_P) =3D=3D 0 || (Pml5[Pml5Index] & > > IA32_PG_PMNT) !=3D 0) { > > // > > - // If the PML4 entry is not present or is masked, skip it > > + // If the PML5 entry is not present or is masked, skip it > > // > > continue; > > } > > - Pdpt =3D (UINT64*)(UINTN)(Pml4[Pml4Index] & ~mAddressEncMask & > > gPhyMask); > > - PML4EIgnore =3D FALSE; > > - for (PdptIndex =3D 0; PdptIndex < EFI_PAGE_SIZE / sizeof (*Pdpt); > > PdptIndex++) { > > - if ((Pdpt[PdptIndex] & IA32_PG_P) =3D=3D 0 || (Pdpt[PdptIndex] = & > > IA32_PG_PMNT) !=3D 0) { > > + Pml4 =3D (UINT64*)(UINTN)(Pml5[Pml5Index] & gPhyMask); > > + for (Pml4Index =3D 0; Pml4Index < EFI_PAGE_SIZE / sizeof (*Pml4); > > Pml4Index++) { > > + if ((Pml4[Pml4Index] & IA32_PG_P) =3D=3D 0 || (Pml4[Pml4Index] = & > > IA32_PG_PMNT) !=3D 0) { > > // > > - // If the PDPT entry is not present or is masked, skip it > > + // If the PML4 entry is not present or is masked, skip it > > // > > - if ((Pdpt[PdptIndex] & IA32_PG_PMNT) !=3D 0) { > > - // > > - // If the PDPT entry is masked, we will ignore checking the > > PML4 entry > > - // > > - PML4EIgnore =3D TRUE; > > - } > > continue; > > } > > - if ((Pdpt[PdptIndex] & IA32_PG_PS) =3D=3D 0) { > > - // > > - // It's not 1-GByte pages entry, it should be a PDPT entry, > > - // we will not check PML4 entry more > > - // > > - PML4EIgnore =3D TRUE; > > - Pdt =3D (UINT64*)(UINTN)(Pdpt[PdptIndex] & ~mAddressEncMask > > & gPhyMask); > > - PDPTEIgnore =3D FALSE; > > - for (PdtIndex =3D 0; PdtIndex < EFI_PAGE_SIZE / sizeof(*Pdt); > > PdtIndex++) { > > - if ((Pdt[PdtIndex] & IA32_PG_P) =3D=3D 0 || (Pdt[PdtIndex] = & > > IA32_PG_PMNT) !=3D 0) { > > + Pdpt =3D (UINT64*)(UINTN)(Pml4[Pml4Index] & ~mAddressEncMask & > > gPhyMask); > > + PML4EIgnore =3D FALSE; > > + for (PdptIndex =3D 0; PdptIndex < EFI_PAGE_SIZE / sizeof (*Pdpt= ); > > PdptIndex++) { > > + if ((Pdpt[PdptIndex] & IA32_PG_P) =3D=3D 0 || (Pdpt[PdptIndex= ] & > > IA32_PG_PMNT) !=3D 0) { > > + // > > + // If the PDPT entry is not present or is masked, skip it > > + // > > + if ((Pdpt[PdptIndex] & IA32_PG_PMNT) !=3D 0) { > > // > > - // If the PD entry is not present or is masked, skip it > > + // If the PDPT entry is masked, we will ignore checking t= he > > PML4 entry > > // > > - if ((Pdt[PdtIndex] & IA32_PG_PMNT) !=3D 0) { > > + PML4EIgnore =3D TRUE; > > + } > > + continue; > > + } > > + if ((Pdpt[PdptIndex] & IA32_PG_PS) =3D=3D 0) { > > + // > > + // It's not 1-GByte pages entry, it should be a PDPT entry, > > + // we will not check PML4 entry more > > + // > > + PML4EIgnore =3D TRUE; > > + Pdt =3D (UINT64*)(UINTN)(Pdpt[PdptIndex] & > > ~mAddressEncMask & gPhyMask); > > + PDPTEIgnore =3D FALSE; > > + for (PdtIndex =3D 0; PdtIndex < EFI_PAGE_SIZE / sizeof(*Pdt= ); > > PdtIndex++) { > > + if ((Pdt[PdtIndex] & IA32_PG_P) =3D=3D 0 || (Pdt[PdtIndex= ] & > > IA32_PG_PMNT) !=3D 0) { > > + // > > + // If the PD entry is not present or is masked, skip it > > + // > > + if ((Pdt[PdtIndex] & IA32_PG_PMNT) !=3D 0) { > > + // > > + // If the PD entry is masked, we will not PDPT entry > > more > > + // > > + PDPTEIgnore =3D TRUE; > > + } > > + continue; > > + } > > + if ((Pdt[PdtIndex] & IA32_PG_PS) =3D=3D 0) { > > // > > - // If the PD entry is masked, we will not PDPT entry mo= re > > + // It's not 2 MByte page table entry, it should be PD e= ntry > > + // we will find the entry has the smallest access recor= d > > value > > // > > PDPTEIgnore =3D TRUE; > > + Acc =3D GetAndUpdateAccNum (Pdt + PdtIndex); > > + if (Acc < MinAcc) { > > + // > > + // If the PD entry has the smallest access record val= ue, > > + // save the Page address to be released > > + // > > + MinAcc =3D Acc; > > + MinPml5 =3D Pml5Index; > > + MinPml4 =3D Pml4Index; > > + MinPdpt =3D PdptIndex; > > + MinPdt =3D PdtIndex; > > + ReleasePageAddress =3D Pdt + PdtIndex; > > + } > > } > > - continue; > > } > > - if ((Pdt[PdtIndex] & IA32_PG_PS) =3D=3D 0) { > > + if (!PDPTEIgnore) { > > // > > - // It's not 2 MByte page table entry, it should be PD ent= ry > > - // we will find the entry has the smallest access record = value > > + // If this PDPT entry has no PDT entries pointer to 4 KBy= te > > pages, > > + // it should only has the entries point to 2 MByte Pages > > // > > - PDPTEIgnore =3D TRUE; > > - Acc =3D GetAndUpdateAccNum (Pdt + PdtIndex); > > + Acc =3D GetAndUpdateAccNum (Pdpt + PdptIndex); > > if (Acc < MinAcc) { > > // > > - // If the PD entry has the smallest access record value= , > > + // If the PDPT entry has the smallest access record val= ue, > > // save the Page address to be released > > // > > MinAcc =3D Acc; > > + MinPml5 =3D Pml5Index; > > MinPml4 =3D Pml4Index; > > MinPdpt =3D PdptIndex; > > - MinPdt =3D PdtIndex; > > - ReleasePageAddress =3D Pdt + PdtIndex; > > + MinPdt =3D (UINTN)-1; > > + ReleasePageAddress =3D Pdpt + PdptIndex; > > } > > } > > } > > - if (!PDPTEIgnore) { > > - // > > - // If this PDPT entry has no PDT entries pointer to 4 KByte > > pages, > > - // it should only has the entries point to 2 MByte Pages > > - // > > - Acc =3D GetAndUpdateAccNum (Pdpt + PdptIndex); > > - if (Acc < MinAcc) { > > - // > > - // If the PDPT entry has the smallest access record value= , > > - // save the Page address to be released > > - // > > - MinAcc =3D Acc; > > - MinPml4 =3D Pml4Index; > > - MinPdpt =3D PdptIndex; > > - MinPdt =3D (UINTN)-1; > > - ReleasePageAddress =3D Pdpt + PdptIndex; > > - } > > - } > > } > > - } > > - if (!PML4EIgnore) { > > - // > > - // If PML4 entry has no the PDPT entry pointer to 2 MByte pages= , > > - // it should only has the entries point to 1 GByte Pages > > - // > > - Acc =3D GetAndUpdateAccNum (Pml4 + Pml4Index); > > - if (Acc < MinAcc) { > > + if (!PML4EIgnore) { > > // > > - // If the PML4 entry has the smallest access record value, > > - // save the Page address to be released > > + // If PML4 entry has no the PDPT entry pointer to 2 MByte pag= es, > > + // it should only has the entries point to 1 GByte Pages > > // > > - MinAcc =3D Acc; > > - MinPml4 =3D Pml4Index; > > - MinPdpt =3D (UINTN)-1; > > - MinPdt =3D (UINTN)-1; > > - ReleasePageAddress =3D Pml4 + Pml4Index; > > + Acc =3D GetAndUpdateAccNum (Pml4 + Pml4Index); > > + if (Acc < MinAcc) { > > + // > > + // If the PML4 entry has the smallest access record value, > > + // save the Page address to be released > > + // > > + MinAcc =3D Acc; > > + MinPml5 =3D Pml5Index; > > + MinPml4 =3D Pml4Index; > > + MinPdpt =3D (UINTN)-1; > > + MinPdt =3D (UINTN)-1; > > + ReleasePageAddress =3D Pml4 + Pml4Index; > > + } > > } > > } > > } > > @@ -588,6 +703,7 @@ ReclaimPages ( > > // > > // If 4 KByte Page Table is released, check the PDPT entry > > // > > + Pml4 =3D (UINT64 *) (UINTN) (Pml5[MinPml5] & gPhyMask); > > Pdpt =3D (UINT64*)(UINTN)(Pml4[MinPml4] & ~mAddressEncMask & > > gPhyMask); > > SubEntriesNum =3D GetSubEntriesNum(Pdpt + MinPdpt); > > if (SubEntriesNum =3D=3D 0) { > > @@ -679,7 +795,7 @@ SmiDefaultPFHandler ( > > ) > > { > > UINT64 *PageTable; > > - UINT64 *Pml4; > > + UINT64 *PageTableTop; > > UINT64 PFAddress; > > UINTN StartBit; > > UINTN EndBit; > > @@ -690,6 +806,8 @@ SmiDefaultPFHandler ( > > UINTN PageAttribute; > > EFI_STATUS Status; > > UINT64 *UpperEntry; > > + BOOLEAN Enable5LevelPaging; > > + IA32_CR4 Cr4; > > > > // > > // Set default SMM page attribute > > @@ -699,9 +817,12 @@ SmiDefaultPFHandler ( > > PageAttribute =3D 0; > > > > EndBit =3D 0; > > - Pml4 =3D (UINT64*)(AsmReadCr3 () & gPhyMask); > > + PageTableTop =3D (UINT64*)(AsmReadCr3 () & gPhyMask); > > PFAddress =3D AsmReadCr2 (); > > > > + Cr4.UintN =3D AsmReadCr4 (); > > + Enable5LevelPaging =3D (BOOLEAN) (Cr4.Bits.LA57 !=3D 0); > > + > > Status =3D GetPlatformPageTableAttribute (PFAddress, &PageSize, > > &NumOfPages, &PageAttribute); > > // > > // If platform not support page table attribute, set default SMM pa= ge > > attribute > > @@ -755,9 +876,9 @@ SmiDefaultPFHandler ( > > } > > > > for (Index =3D 0; Index < NumOfPages; Index++) { > > - PageTable =3D Pml4; > > + PageTable =3D PageTableTop; > > UpperEntry =3D NULL; > > - for (StartBit =3D 39; StartBit > EndBit; StartBit -=3D 9) { > > + for (StartBit =3D Enable5LevelPaging ? 48 : 39; StartBit > EndBit= ; StartBit > > -=3D 9) { > > PTIndex =3D BitFieldRead64 (PFAddress, StartBit, StartBit + 8); > > if ((PageTable[PTIndex] & IA32_PG_P) =3D=3D 0) { > > // > > @@ -941,13 +1062,20 @@ SetPageTableAttributes ( > > UINTN Index2; > > UINTN Index3; > > UINTN Index4; > > + UINTN Index5; > > UINT64 *L1PageTable; > > UINT64 *L2PageTable; > > UINT64 *L3PageTable; > > UINT64 *L4PageTable; > > + UINT64 *L5PageTable; > > BOOLEAN IsSplitted; > > BOOLEAN PageTableSplitted; > > BOOLEAN CetEnabled; > > + IA32_CR4 Cr4; > > + BOOLEAN Enable5LevelPaging; > > + > > + Cr4.UintN =3D AsmReadCr4 (); > > + Enable5LevelPaging =3D (BOOLEAN) (Cr4.Bits.LA57 =3D=3D 1); > > > > // > > // Don't do this if > > @@ -991,44 +1119,59 @@ SetPageTableAttributes ( > > do { > > DEBUG ((DEBUG_INFO, "Start...\n")); > > PageTableSplitted =3D FALSE; > > - > > - L4PageTable =3D (UINT64 *)GetPageTableBase (); > > - SmmSetMemoryAttributesEx > > ((EFI_PHYSICAL_ADDRESS)(UINTN)L4PageTable, SIZE_4KB, > > EFI_MEMORY_RO, &IsSplitted); > > - PageTableSplitted =3D (PageTableSplitted || IsSplitted); > > - > > - for (Index4 =3D 0; Index4 < SIZE_4KB/sizeof(UINT64); Index4++) { > > - L3PageTable =3D (UINT64 *)(UINTN)(L4PageTable[Index4] & > > ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > - if (L3PageTable =3D=3D NULL) { > > - continue; > > - } > > - > > - SmmSetMemoryAttributesEx > > ((EFI_PHYSICAL_ADDRESS)(UINTN)L3PageTable, SIZE_4KB, > > EFI_MEMORY_RO, &IsSplitted); > > + L5PageTable =3D NULL; > > + if (Enable5LevelPaging) { > > + L5PageTable =3D (UINT64 *)GetPageTableBase (); > > + SmmSetMemoryAttributesEx > > ((EFI_PHYSICAL_ADDRESS)(UINTN)L5PageTable, SIZE_4KB, > > EFI_MEMORY_RO, &IsSplitted); > > PageTableSplitted =3D (PageTableSplitted || IsSplitted); > > + } > > > > - for (Index3 =3D 0; Index3 < SIZE_4KB/sizeof(UINT64); Index3++) = { > > - if ((L3PageTable[Index3] & IA32_PG_PS) !=3D 0) { > > - // 1G > > + for (Index5 =3D 0; Index5 < (Enable5LevelPaging ? > > SIZE_4KB/sizeof(UINT64) : 1); Index5++) { > > + if (Enable5LevelPaging) { > > + L4PageTable =3D (UINT64 *)(UINTN)(L5PageTable[Index5] & > > ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > + if (L4PageTable =3D=3D NULL) { > > continue; > > } > > - L2PageTable =3D (UINT64 *)(UINTN)(L3PageTable[Index3] & > > ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > - if (L2PageTable =3D=3D NULL) { > > + } else { > > + L4PageTable =3D (UINT64 *)GetPageTableBase (); > > + } > > + SmmSetMemoryAttributesEx > > ((EFI_PHYSICAL_ADDRESS)(UINTN)L4PageTable, SIZE_4KB, > > EFI_MEMORY_RO, &IsSplitted); > > + PageTableSplitted =3D (PageTableSplitted || IsSplitted); > > + > > + for (Index4 =3D 0; Index4 < SIZE_4KB/sizeof(UINT64); Index4++) = { > > + L3PageTable =3D (UINT64 *)(UINTN)(L4PageTable[Index4] & > > ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > + if (L3PageTable =3D=3D NULL) { > > continue; > > } > > > > - SmmSetMemoryAttributesEx > > ((EFI_PHYSICAL_ADDRESS)(UINTN)L2PageTable, SIZE_4KB, > > EFI_MEMORY_RO, &IsSplitted); > > + SmmSetMemoryAttributesEx > > ((EFI_PHYSICAL_ADDRESS)(UINTN)L3PageTable, SIZE_4KB, > > EFI_MEMORY_RO, &IsSplitted); > > PageTableSplitted =3D (PageTableSplitted || IsSplitted); > > > > - for (Index2 =3D 0; Index2 < SIZE_4KB/sizeof(UINT64); Index2++= ) { > > - if ((L2PageTable[Index2] & IA32_PG_PS) !=3D 0) { > > - // 2M > > + for (Index3 =3D 0; Index3 < SIZE_4KB/sizeof(UINT64); Index3++= ) { > > + if ((L3PageTable[Index3] & IA32_PG_PS) !=3D 0) { > > + // 1G > > continue; > > } > > - L1PageTable =3D (UINT64 *)(UINTN)(L2PageTable[Index2] & > > ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > - if (L1PageTable =3D=3D NULL) { > > + L2PageTable =3D (UINT64 *)(UINTN)(L3PageTable[Index3] & > > ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > + if (L2PageTable =3D=3D NULL) { > > continue; > > } > > - SmmSetMemoryAttributesEx > > ((EFI_PHYSICAL_ADDRESS)(UINTN)L1PageTable, SIZE_4KB, > > EFI_MEMORY_RO, &IsSplitted); > > + > > + SmmSetMemoryAttributesEx > > ((EFI_PHYSICAL_ADDRESS)(UINTN)L2PageTable, SIZE_4KB, > > EFI_MEMORY_RO, &IsSplitted); > > PageTableSplitted =3D (PageTableSplitted || IsSplitted); > > + > > + for (Index2 =3D 0; Index2 < SIZE_4KB/sizeof(UINT64); Index2= ++) { > > + if ((L2PageTable[Index2] & IA32_PG_PS) !=3D 0) { > > + // 2M > > + continue; > > + } > > + L1PageTable =3D (UINT64 *)(UINTN)(L2PageTable[Index2] & > > ~mAddressEncMask & PAGING_4K_ADDRESS_MASK_64); > > + if (L1PageTable =3D=3D NULL) { > > + continue; > > + } > > + SmmSetMemoryAttributesEx > > ((EFI_PHYSICAL_ADDRESS)(UINTN)L1PageTable, SIZE_4KB, > > EFI_MEMORY_RO, &IsSplitted); > > + PageTableSplitted =3D (PageTableSplitted || IsSplitted); > > + } > > } > > } > > } > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm > > b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm > > index 741e4b7da2..b5e0405b3b 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm > > @@ -69,6 +69,7 @@ extern ASM_PFX(mXdSupported) > > global ASM_PFX(gPatchXdSupported) > > global ASM_PFX(gPatchSmiStack) > > global ASM_PFX(gPatchSmiCr3) > > +global ASM_PFX(m5LevelPagingSupport) > > global ASM_PFX(gcSmiHandlerTemplate) > > global ASM_PFX(gcSmiHandlerSize) > > > > @@ -124,6 +125,17 @@ ProtFlatMode: > > ASM_PFX(gPatchSmiCr3): > > mov cr3, rax > > mov eax, 0x668 ; as cr4.PGE is not set > > here, refresh cr3 > > + > > + DB 0xb1 ; mov cl, > > m5LevelPagingSupport > > +ASM_PFX(m5LevelPagingSupport): DB 0 > > + cmp cl, 0 > > + je SkipEnable5LevelPaging > > + ; > > + ; Enable 5-Level Paging bit > > + ; > > + bts eax, 12 ; Set LA57 bit (bit #12) > > +SkipEnable5LevelPaging: > > + > > mov cr4, rax ; in PreModifyMtrrs() to > > flush TLB. > > ; Load TSS > > sub esp, 8 ; reserve room in stack > > diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c > > b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c > > index e7c78d36fc..63bae5a913 100644 > > --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c > > +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c > > @@ -1,7 +1,7 @@ > > /** @file > > X64 processor specific functions to enable SMM profile. > > > > -Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved. > > +Copyright (c) 2012 - 2019, Intel Corporation. All rights reserved. > > Copyright (c) 2017, AMD Incorporated. All rights reserved.
> > > > SPDX-License-Identifier: BSD-2-Clause-Patent > > @@ -147,9 +147,14 @@ RestorePageTableAbove4G ( > > BOOLEAN Existed; > > UINTN Index; > > UINTN PFIndex; > > + IA32_CR4 Cr4; > > + BOOLEAN Enable5LevelPaging; > > > > ASSERT ((PageTable !=3D NULL) && (IsValidPFAddress !=3D NULL)); > > > > + Cr4.UintN =3D AsmReadCr4 (); > > + Enable5LevelPaging =3D (BOOLEAN) (Cr4.Bits.LA57 =3D=3D 1); > > + > > // > > // If page fault address is 4GB above. > > // > > @@ -161,38 +166,48 @@ RestorePageTableAbove4G ( > > // > > Existed =3D FALSE; > > PageTable =3D (UINT64*)(AsmReadCr3 () & PHYSICAL_ADDRESS_MASK); > > - PTIndex =3D BitFieldRead64 (PFAddress, 39, 47); > > - if ((PageTable[PTIndex] & IA32_PG_P) !=3D 0) { > > - // PML4E > > - PageTable =3D (UINT64*)(UINTN)(PageTable[PTIndex] & > > ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); > > - PTIndex =3D BitFieldRead64 (PFAddress, 30, 38); > > + PTIndex =3D 0; > > + if (Enable5LevelPaging) { > > + PTIndex =3D BitFieldRead64 (PFAddress, 48, 56); > > + } > > + if ((!Enable5LevelPaging) || ((PageTable[PTIndex] & IA32_PG_P) !=3D= 0)) { > > + // PML5E > > + if (Enable5LevelPaging) { > > + PageTable =3D (UINT64*)(UINTN)(PageTable[PTIndex] & > > ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); > > + } > > + PTIndex =3D BitFieldRead64 (PFAddress, 39, 47); > > if ((PageTable[PTIndex] & IA32_PG_P) !=3D 0) { > > - // PDPTE > > + // PML4E > > PageTable =3D (UINT64*)(UINTN)(PageTable[PTIndex] & > > ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); > > - PTIndex =3D BitFieldRead64 (PFAddress, 21, 29); > > - // PD > > - if ((PageTable[PTIndex] & IA32_PG_PS) !=3D 0) { > > - // > > - // 2MB page > > - // > > - Address =3D (UINT64)(PageTable[PTIndex] & ~mAddressEncMask & > > PHYSICAL_ADDRESS_MASK); > > - if ((Address & ~((1ull << 21) - 1)) =3D=3D ((PFAddress & > > PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)))) { > > - Existed =3D TRUE; > > - } > > - } else { > > - // > > - // 4KB page > > - // > > - PageTable =3D (UINT64*)(UINTN)(PageTable[PTIndex] & > > ~mAddressEncMask& PHYSICAL_ADDRESS_MASK); > > - if (PageTable !=3D 0) { > > + PTIndex =3D BitFieldRead64 (PFAddress, 30, 38); > > + if ((PageTable[PTIndex] & IA32_PG_P) !=3D 0) { > > + // PDPTE > > + PageTable =3D (UINT64*)(UINTN)(PageTable[PTIndex] & > > ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); > > + PTIndex =3D BitFieldRead64 (PFAddress, 21, 29); > > + // PD > > + if ((PageTable[PTIndex] & IA32_PG_PS) !=3D 0) { > > // > > - // When there is a valid entry to map to 4KB page, need not > > create a new entry to map 2MB. > > + // 2MB page > > // > > - PTIndex =3D BitFieldRead64 (PFAddress, 12, 20); > > Address =3D (UINT64)(PageTable[PTIndex] & ~mAddressEncMask > > & PHYSICAL_ADDRESS_MASK); > > - if ((Address & ~((1ull << 12) - 1)) =3D=3D (PFAddress & > > PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) { > > + if ((Address & ~((1ull << 21) - 1)) =3D=3D ((PFAddress & > > PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)))) { > > Existed =3D TRUE; > > } > > + } else { > > + // > > + // 4KB page > > + // > > + PageTable =3D (UINT64*)(UINTN)(PageTable[PTIndex] & > > ~mAddressEncMask& PHYSICAL_ADDRESS_MASK); > > + if (PageTable !=3D 0) { > > + // > > + // When there is a valid entry to map to 4KB page, need n= ot > > create a new entry to map 2MB. > > + // > > + PTIndex =3D BitFieldRead64 (PFAddress, 12, 20); > > + Address =3D (UINT64)(PageTable[PTIndex] & > > ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); > > + if ((Address & ~((1ull << 12) - 1)) =3D=3D (PFAddress & > > PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) { > > + Existed =3D TRUE; > > + } > > + } > > } > > } > > } > > @@ -221,6 +236,11 @@ RestorePageTableAbove4G ( > > // > > PageTable =3D (UINT64*)(AsmReadCr3 () & PHYSICAL_ADDRESS_MASK); > > PFAddress =3D AsmReadCr2 (); > > + // PML5E > > + if (Enable5LevelPaging) { > > + PTIndex =3D BitFieldRead64 (PFAddress, 48, 56); > > + PageTable =3D (UINT64*)(UINTN)(PageTable[PTIndex] & > > ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); > > + } > > // PML4E > > PTIndex =3D BitFieldRead64 (PFAddress, 39, 47); > > PageTable =3D (UINT64*)(UINTN)(PageTable[PTIndex] & > > ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); > > -- > > 2.21.0.windows.1 > > > > > >=20