[edk2-devel] [PATCH v5 2/2] UefiCpuPkg/PiSmmCpuDxeSmm: Return level paging type for Internal CR3

Sheng Wei w.sheng at intel.com
Thu Nov 5 04:05:41 UTC 2020


If mInternalCr3 is non zero, it will use the page table from mInternalCr3.
And it will use mInternalIs5LevelPaging to reflect the paging type.
If mInternalCr3 is zero, it will use the page table from CR3, and reflect
 the paging type by CR4 LA57 bit.

This patch is a bug fix when enable CET feature with 5 level paging.
The page table of SMM shadows shack memory is generated in PiCpuSmmEntry().
This page table is not set to CR3 in PiCpuSmmEntry(), it is only for
 SMI entry. When CET feature is enabled, we need to set some attributes for
 SMM shadows shack memory in PiCpuSmmEntry().
We set this page table to mInternalCr3 for update the memory attribute.
The CR4 LA57 bit does not reflect the paging type of mInternalCr3,
 so we need to use a virable (mInternalIs5LevelPaging) to reflect if
 mInternalCr3 is 5 level paging or 4 level paging.
We also use the same function to update the memory attribue with the
 page table in CR3, use CR4 LA57 bit to reflect the paging type of CR3.
So we need to use GetPageTableBase() and Is5LevelPageTableBase() to return
 the page table and its paging type for GetPageTableEntry() when set the
 memory attribute.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3015

Signed-off-by: Sheng Wei <w.sheng at intel.com>
Cc: Eric Dong <eric.dong at intel.com>
Cc: Ray Ni <ray.ni at intel.com>
Cc: Laszlo Ersek <lersek at redhat.com>
Cc: Rahul Kumar <rahul1.kumar at intel.com>
Cc: Jiewen Yao <jiewen.yao at intel.com>
---
 UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h         | 10 +++++
 UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c | 47 ++++++++++++++++++++--
 UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c            |  2 +
 3 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
index 7fb3a2d9e4..3eb6af62a7 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
@@ -951,6 +951,16 @@ GetPageTableBase (
   VOID
   );
 
+/**
+  This function set the internal page table type to 5 level paging or 4 level paging.
+
+  @param Is5LevelPaging TRUE means 5 level paging. FALSE means 4 level paging.
+**/
+VOID
+SetPageTableType (
+  IN BOOLEAN  Is5LevelPaging
+  );
+
 /**
   This function sets the attributes for the memory region specified by BaseAddress and
   Length from their current attributes to the attributes specified by Attributes.
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
index d67f036aea..800394afc7 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c
@@ -33,6 +33,7 @@ PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = {
 };
 
 UINTN  mInternalCr3;
+BOOLEAN mInternalIs5LevelPaging = FALSE;
 
 /**
   Set the internal page table base address.
@@ -65,6 +66,48 @@ GetPageTableBase (
   return (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);
 }
 
+/**
+  This function set the internal page table type to 5 level paging or 4 level paging.
+
+  @param Is5LevelPaging TRUE means 5 level paging. FALSE means 4 level paging.
+**/
+VOID
+SetPageTableType (
+  IN BOOLEAN  Is5LevelPaging
+  )
+{
+  mInternalIs5LevelPaging = Is5LevelPaging;
+}
+
+/**
+  Return if the page table is 5 level paging.
+
+  @return TRUE  The page table base is 5 level paging.
+  @return FALSE The page table base is 4 level paging.
+**/
+STATIC
+BOOLEAN
+Is5LevelPageTableBase (
+  VOID
+  )
+{
+  IA32_CR4              Cr4;
+
+  //
+  // If mInternalCr3 is non zero, it will use the page table from mInternalCr3.
+  // And it will use mInternalIs5LevelPaging to reflect the paging type.
+  //
+  if (mInternalCr3 != 0) {
+    return mInternalIs5LevelPaging;
+  }
+
+  //
+  // If use page table from CR3, reflect the paging type by CR4 LA57 bit.
+  //
+  Cr4.UintN = AsmReadCr4 ();
+  return (BOOLEAN) (Cr4.Bits.LA57 == 1);
+}
+
 /**
   Return length according to page attributes.
 
@@ -131,7 +174,6 @@ GetPageTableEntry (
   UINT64                *L3PageTable;
   UINT64                *L4PageTable;
   UINT64                *L5PageTable;
-  IA32_CR4              Cr4;
   BOOLEAN               Enable5LevelPaging;
 
   Index5 = ((UINTN)RShiftU64 (Address, 48)) & PAGING_PAE_INDEX_MASK;
@@ -140,8 +182,7 @@ GetPageTableEntry (
   Index2 = ((UINTN)Address >> 21) & PAGING_PAE_INDEX_MASK;
   Index1 = ((UINTN)Address >> 12) & PAGING_PAE_INDEX_MASK;
 
-  Cr4.UintN = AsmReadCr4 ();
-  Enable5LevelPaging = (BOOLEAN) (Cr4.Bits.LA57 == 1);
+  Enable5LevelPaging = Is5LevelPageTableBase ();
 
   if (sizeof(UINTN) == sizeof(UINT64)) {
     if (Enable5LevelPaging) {
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
index 810985df20..64f796e0d5 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
@@ -387,6 +387,8 @@ SmmInitPageTable (
   SetSubEntriesNum (Pml4Entry, 3);
   PTEntry = Pml4Entry;
 
+  SetPageTableType (m5LevelPagingNeeded);
+
   if (m5LevelPagingNeeded) {
     //
     // Fill PML5 entry
-- 
2.16.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#67025): https://edk2.groups.io/g/devel/message/67025
Mute This Topic: https://groups.io/mt/78044934/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list