]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiPayloadPkg/PayloadEntry: Inherit 4/5-level paging from bootloader
authorNi, Ray <ray.ni@intel.com>
Fri, 6 Aug 2021 08:16:26 +0000 (16:16 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 8 Dec 2021 04:08:21 +0000 (04:08 +0000)
The patch removes the dep on PcdUse5LevelPageTable.
Now the payload inherits the 5-level paging setting from
bootloader in IA-32e mode and uses 4-level paging in
legacy protected mode.

This fix the potential issue when bootloader enables 5-level paging
but 64bit payload sets 4-level page table to CR3 resulting CPU
exception because PcdUse5LevelPageTable is FALSE.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Reviewed-by: Maurice Ma <maurice.ma@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf
UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf
UefiPayloadPkg/UefiPayloadEntry/X64/VirtualMemory.c

index 07a678bd461c85bdb43e703d296cc7969e9123db..1847d6481a235852d80889dcb009acde2891a95d 100644 (file)
@@ -79,7 +79,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES\r
-  gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable                  ## SOMETIMES_CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                            ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize                            ## CONSUMES\r
 \r
index a8576305ad9fd1c520d037df55c43997cea28ba9..80af5afe0a3f1a241b02ef43fb2681c6ff925681 100644 (file)
@@ -85,7 +85,6 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES\r
-  gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable                  ## SOMETIMES_CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase                            ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbSize                            ## CONSUMES\r
 \r
index 1272d894133b8ceead54871bcbb0bbcc9a792ebf..ac0d58e685c82bf2163fae936c9e7819da38c29c 100644 (file)
@@ -15,7 +15,7 @@
     2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel\r
     3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel\r
 \r
-Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
 \r
 SPDX-License-Identifier: BSD-2-Clause-Patent\r
@@ -685,31 +685,30 @@ CreateIdentityMappingPageTables (
   IN UINTN                 GhcbSize\r
   )\r
 {\r
-  UINT32                                       RegEax;\r
-  CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX  EcxFlags;\r
-  UINT32                                       RegEdx;\r
-  UINT8                                        PhysicalAddressBits;\r
-  EFI_PHYSICAL_ADDRESS                         PageAddress;\r
-  UINTN                                        IndexOfPml5Entries;\r
-  UINTN                                        IndexOfPml4Entries;\r
-  UINTN                                        IndexOfPdpEntries;\r
-  UINTN                                        IndexOfPageDirectoryEntries;\r
-  UINT32                                       NumberOfPml5EntriesNeeded;\r
-  UINT32                                       NumberOfPml4EntriesNeeded;\r
-  UINT32                                       NumberOfPdpEntriesNeeded;\r
-  PAGE_MAP_AND_DIRECTORY_POINTER               *PageMapLevel5Entry;\r
-  PAGE_MAP_AND_DIRECTORY_POINTER               *PageMapLevel4Entry;\r
-  PAGE_MAP_AND_DIRECTORY_POINTER               *PageMap;\r
-  PAGE_MAP_AND_DIRECTORY_POINTER               *PageDirectoryPointerEntry;\r
-  PAGE_TABLE_ENTRY                             *PageDirectoryEntry;\r
-  UINTN                                        TotalPagesNum;\r
-  UINTN                                        BigPageAddress;\r
-  VOID                                         *Hob;\r
-  BOOLEAN                                      Page5LevelSupport;\r
-  BOOLEAN                                      Page1GSupport;\r
-  PAGE_TABLE_1G_ENTRY                          *PageDirectory1GEntry;\r
-  UINT64                                       AddressEncMask;\r
-  IA32_CR4                                     Cr4;\r
+  UINT32                          RegEax;\r
+  UINT32                          RegEdx;\r
+  UINT8                           PhysicalAddressBits;\r
+  EFI_PHYSICAL_ADDRESS            PageAddress;\r
+  UINTN                           IndexOfPml5Entries;\r
+  UINTN                           IndexOfPml4Entries;\r
+  UINTN                           IndexOfPdpEntries;\r
+  UINTN                           IndexOfPageDirectoryEntries;\r
+  UINT32                          NumberOfPml5EntriesNeeded;\r
+  UINT32                          NumberOfPml4EntriesNeeded;\r
+  UINT32                          NumberOfPdpEntriesNeeded;\r
+  PAGE_MAP_AND_DIRECTORY_POINTER  *PageMapLevel5Entry;\r
+  PAGE_MAP_AND_DIRECTORY_POINTER  *PageMapLevel4Entry;\r
+  PAGE_MAP_AND_DIRECTORY_POINTER  *PageMap;\r
+  PAGE_MAP_AND_DIRECTORY_POINTER  *PageDirectoryPointerEntry;\r
+  PAGE_TABLE_ENTRY                *PageDirectoryEntry;\r
+  UINTN                           TotalPagesNum;\r
+  UINTN                           BigPageAddress;\r
+  VOID                            *Hob;\r
+  BOOLEAN                         Enable5LevelPaging;\r
+  BOOLEAN                         Page1GSupport;\r
+  PAGE_TABLE_1G_ENTRY             *PageDirectory1GEntry;\r
+  UINT64                          AddressEncMask;\r
+  IA32_CR4                        Cr4;\r
 \r
   //\r
   // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings\r
@@ -748,22 +747,16 @@ CreateIdentityMappingPageTables (
     }\r
   }\r
 \r
-  Page5LevelSupport = FALSE;\r
-  if (PcdGetBool (PcdUse5LevelPageTable)) {\r
-    AsmCpuidEx (\r
-      CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS,\r
-      CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO,\r
-      NULL,\r
-      &EcxFlags.Uint32,\r
-      NULL,\r
-      NULL\r
-      );\r
-    if (EcxFlags.Bits.FiveLevelPage != 0) {\r
-      Page5LevelSupport = TRUE;\r
-    }\r
-  }\r
+  //\r
+  // Check CR4.LA57[bit12] to determin whether 5-Level Paging is enabled.\r
+  // Because this code runs at both IA-32e (64bit) mode and legacy protected (32bit) mode,\r
+  // below logic inherits the 5-level paging setting from bootloader in IA-32e mode\r
+  // and uses 4-level paging in legacy protected mode.\r
+  //\r
+  Cr4.UintN          = AsmReadCr4 ();\r
+  Enable5LevelPaging = (BOOLEAN)(Cr4.Bits.LA57 == 1);\r
 \r
-  DEBUG ((DEBUG_INFO, "AddressBits=%u 5LevelPaging=%u 1GPage=%u\n", PhysicalAddressBits, Page5LevelSupport, Page1GSupport));\r
+  DEBUG ((DEBUG_INFO, "PayloadEntry: AddressBits=%u 5LevelPaging=%u 1GPage=%u\n", PhysicalAddressBits, Enable5LevelPaging, Page1GSupport));\r
 \r
   //\r
   // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses\r
@@ -771,7 +764,7 @@ CreateIdentityMappingPageTables (
   //  due to either unsupported by HW, or disabled by PCD.\r
   //\r
   ASSERT (PhysicalAddressBits <= 52);\r
-  if (!Page5LevelSupport && (PhysicalAddressBits > 48)) {\r
+  if (!Enable5LevelPaging && (PhysicalAddressBits > 48)) {\r
     PhysicalAddressBits = 48;\r
   }\r
 \r
@@ -806,7 +799,7 @@ CreateIdentityMappingPageTables (
   //\r
   // Substract the one page occupied by PML5 entries if 5-Level Paging is disabled.\r
   //\r
-  if (!Page5LevelSupport) {\r
+  if (!Enable5LevelPaging) {\r
     TotalPagesNum--;\r
   }\r
 \r
@@ -826,7 +819,7 @@ CreateIdentityMappingPageTables (
   // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.\r
   //\r
   PageMap = (VOID *)BigPageAddress;\r
-  if (Page5LevelSupport) {\r
+  if (Enable5LevelPaging) {\r
     //\r
     // By architecture only one PageMapLevel5 exists - so lets allocate storage for it.\r
     //\r
@@ -848,7 +841,7 @@ CreateIdentityMappingPageTables (
     PageMapLevel4Entry = (VOID *)BigPageAddress;\r
     BigPageAddress    += SIZE_4KB;\r
 \r
-    if (Page5LevelSupport) {\r
+    if (Enable5LevelPaging) {\r
       //\r
       // Make a PML5 Entry\r
       //\r
@@ -942,10 +935,7 @@ CreateIdentityMappingPageTables (
     ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER));\r
   }\r
 \r
-  if (Page5LevelSupport) {\r
-    Cr4.UintN     = AsmReadCr4 ();\r
-    Cr4.Bits.LA57 = 1;\r
-    AsmWriteCr4 (Cr4.UintN);\r
+  if (Enable5LevelPaging) {\r
     //\r
     // For the PML5 entries we are not using fill in a null entry.\r
     //\r