]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/PiSmmCpu: Enable 5L paging only when phy addr line > 48
authorRay Ni <ray.ni@intel.com>
Thu, 5 Sep 2019 22:18:47 +0000 (06:18 +0800)
committerRay Ni <ray.ni@intel.com>
Fri, 13 Sep 2019 08:20:54 +0000 (16:20 +0800)
Today's behavior is to enable 5l paging when CPU supports it
(CPUID[7,0].ECX.BIT[16] is set).

The patch changes the behavior to enable 5l paging when two
conditions are both met:
1. CPU supports it;
2. The max physical address bits is bigger than 48.

Because 4-level paging can support to address physical address up to
2^48 - 1, there is no need to enable 5-level paging with max
physical address bits <= 48.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm

index 733d107efdbf3606d4411697cf1396aee3e19547..e5c4788c13d7637d3db7edffbc0a20c3740f55f8 100644 (file)
@@ -16,8 +16,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 LIST_ENTRY                          mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool);\r
 BOOLEAN                             m1GPageTableSupport = FALSE;\r
 BOOLEAN                             mCpuSmmRestrictedMemoryAccess;\r
-BOOLEAN                             m5LevelPagingSupport;\r
-X86_ASSEMBLY_PATCH_LABEL            gPatch5LevelPagingSupport;\r
+BOOLEAN                             m5LevelPagingNeeded;\r
+X86_ASSEMBLY_PATCH_LABEL            gPatch5LevelPagingNeeded;\r
 \r
 /**\r
   Disable CET.\r
@@ -63,28 +63,45 @@ Is1GPageSupport (
 }\r
 \r
 /**\r
-  Check if 5-level paging is supported by processor or not.\r
-\r
-  @retval TRUE   5-level paging is supported.\r
-  @retval FALSE  5-level paging is not supported.\r
+  The routine returns TRUE when CPU supports it (CPUID[7,0].ECX.BIT[16] is set) and\r
+  the max physical address bits is bigger than 48. Because 4-level paging can support\r
+  to address physical address up to 2^48 - 1, there is no need to enable 5-level paging\r
+  with max physical address bits <= 48.\r
 \r
+  @retval TRUE  5-level paging enabling is needed.\r
+  @retval FALSE 5-level paging enabling is not needed.\r
 **/\r
 BOOLEAN\r
-Is5LevelPagingSupport (\r
+Is5LevelPagingNeeded (\r
   VOID\r
   )\r
 {\r
-  CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX EcxFlags;\r
+  CPUID_VIR_PHY_ADDRESS_SIZE_EAX              VirPhyAddressSize;\r
+  CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX ExtFeatureEcx;\r
+  UINT32                                      MaxExtendedFunctionId;\r
 \r
+  AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunctionId, NULL, NULL, NULL);\r
+  if (MaxExtendedFunctionId >= CPUID_VIR_PHY_ADDRESS_SIZE) {\r
+    AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);\r
+  } else {\r
+    VirPhyAddressSize.Bits.PhysicalAddressBits = 36;\r
+  }\r
   AsmCpuidEx (\r
     CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS,\r
     CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO,\r
-    NULL,\r
-    NULL,\r
-    &EcxFlags.Uint32,\r
-    NULL\r
+    NULL, NULL, &ExtFeatureEcx.Uint32, NULL\r
     );\r
-  return (BOOLEAN) (EcxFlags.Bits.FiveLevelPage != 0);\r
+  DEBUG ((\r
+    DEBUG_INFO, "PhysicalAddressBits = %d, 5LPageTable = %d.\n",\r
+    VirPhyAddressSize.Bits.PhysicalAddressBits, ExtFeatureEcx.Bits.FiveLevelPage\r
+    ));\r
+\r
+  if (VirPhyAddressSize.Bits.PhysicalAddressBits > 4 * 9 + 12) {\r
+    ASSERT (ExtFeatureEcx.Bits.FiveLevelPage == 1);\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
 }\r
 \r
 /**\r
@@ -190,7 +207,7 @@ SetStaticPageTable (
   //  when 5-Level Paging is disabled.\r
   //\r
   ASSERT (mPhysicalAddressBits <= 52);\r
-  if (!m5LevelPagingSupport && mPhysicalAddressBits > 48) {\r
+  if (!m5LevelPagingNeeded && mPhysicalAddressBits > 48) {\r
     mPhysicalAddressBits = 48;\r
   }\r
 \r
@@ -217,7 +234,7 @@ SetStaticPageTable (
 \r
   PageMapLevel4Entry = PageMap;\r
   PageMapLevel5Entry = NULL;\r
-  if (m5LevelPagingSupport) {\r
+  if (m5LevelPagingNeeded) {\r
     //\r
     // By architecture only one PageMapLevel5 exists - so lets allocate storage for it.\r
     //\r
@@ -233,7 +250,7 @@ SetStaticPageTable (
     // So lets allocate space for them and fill them in in the IndexOfPml4Entries loop.\r
     // When 5-Level Paging is disabled, below allocation happens only once.\r
     //\r
-    if (m5LevelPagingSupport) {\r
+    if (m5LevelPagingNeeded) {\r
       PageMapLevel4Entry = (UINT64 *) ((*PageMapLevel5Entry) & ~mAddressEncMask & gPhyMask);\r
       if (PageMapLevel4Entry == NULL) {\r
         PageMapLevel4Entry = AllocatePageTableMemory (1);\r
@@ -336,10 +353,10 @@ SmmInitPageTable (
 \r
   mCpuSmmRestrictedMemoryAccess = PcdGetBool (PcdCpuSmmRestrictedMemoryAccess);\r
   m1GPageTableSupport           = Is1GPageSupport ();\r
-  m5LevelPagingSupport          = Is5LevelPagingSupport ();\r
+  m5LevelPagingNeeded           = Is5LevelPagingNeeded ();\r
   mPhysicalAddressBits          = CalculateMaximumSupportAddress ();\r
-  PatchInstructionX86 (gPatch5LevelPagingSupport, m5LevelPagingSupport, 1);\r
-  DEBUG ((DEBUG_INFO, "5LevelPaging Support            - %d\n", m5LevelPagingSupport));\r
+  PatchInstructionX86 (gPatch5LevelPagingNeeded, m5LevelPagingNeeded, 1);\r
+  DEBUG ((DEBUG_INFO, "5LevelPaging Needed             - %d\n", m5LevelPagingNeeded));\r
   DEBUG ((DEBUG_INFO, "1GPageTable Support             - %d\n", m1GPageTableSupport));\r
   DEBUG ((DEBUG_INFO, "PcdCpuSmmRestrictedMemoryAccess - %d\n", mCpuSmmRestrictedMemoryAccess));\r
   DEBUG ((DEBUG_INFO, "PhysicalAddressBits             - %d\n", mPhysicalAddressBits));\r
@@ -370,7 +387,7 @@ SmmInitPageTable (
   SetSubEntriesNum (Pml4Entry, 3);\r
   PTEntry = Pml4Entry;\r
 \r
-  if (m5LevelPagingSupport) {\r
+  if (m5LevelPagingNeeded) {\r
     //\r
     // Fill PML5 entry\r
     //\r
index 271492a9d7220b13c8de2b329e2788a60da26ac3..db06d22d51f4804fc939dd6e55450a8f29170b9a 100644 (file)
@@ -69,7 +69,7 @@ extern ASM_PFX(mXdSupported)
 global ASM_PFX(gPatchXdSupported)\r
 global ASM_PFX(gPatchSmiStack)\r
 global ASM_PFX(gPatchSmiCr3)\r
-global ASM_PFX(gPatch5LevelPagingSupport)\r
+global ASM_PFX(gPatch5LevelPagingNeeded)\r
 global ASM_PFX(gcSmiHandlerTemplate)\r
 global ASM_PFX(gcSmiHandlerSize)\r
 \r
@@ -127,7 +127,7 @@ ASM_PFX(gPatchSmiCr3):
     mov     eax, 0x668                   ; as cr4.PGE is not set here, refresh cr3\r
 \r
     mov     cl, strict byte 0            ; source operand will be patched\r
-ASM_PFX(gPatch5LevelPagingSupport):\r
+ASM_PFX(gPatch5LevelPagingNeeded):\r
     cmp     cl, 0\r
     je      SkipEnable5LevelPaging\r
     ;\r