]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
MdeModulePkg/DxeIplPeim: reserve page 0 for NULL pointer detection
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / Ia32 / DxeLoadFunc.c
index 56492653671ea4ecc9e05c64107823a61a2a14eb..6e8ca824d469e9db51405fc673c41d539e750436 100644 (file)
@@ -1,16 +1,10 @@
 /** @file\r
   Ia32-specific functionality for DxeLoad.\r
 \r
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
 \r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -73,7 +67,7 @@ Create4GPageTablesIa32Pae (
   IN EFI_PHYSICAL_ADDRESS   StackBase,\r
   IN UINTN                  StackSize\r
   )\r
-{  \r
+{\r
   UINT8                                         PhysicalAddressBits;\r
   EFI_PHYSICAL_ADDRESS                          PhysicalAddress;\r
   UINTN                                         IndexOfPdpEntries;\r
@@ -99,7 +93,7 @@ Create4GPageTablesIa32Pae (
   NumberOfPdpEntriesNeeded = (UINT32) LShiftU64 (1, (PhysicalAddressBits - 30));\r
 \r
   TotalPagesNum = NumberOfPdpEntriesNeeded + 1;\r
-  PageAddress = (UINTN) AllocatePages (TotalPagesNum);\r
+  PageAddress = (UINTN) AllocatePageTableMemory (TotalPagesNum);\r
   ASSERT (PageAddress != 0);\r
 \r
   PageMap = (VOID *) PageAddress;\r
@@ -112,7 +106,7 @@ Create4GPageTablesIa32Pae (
     //\r
     // Each Directory Pointer entries points to a page of Page Directory entires.\r
     // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.\r
-    //       \r
+    //\r
     PageDirectoryEntry = (VOID *) PageAddress;\r
     PageAddress += SIZE_4KB;\r
 \r
@@ -149,6 +143,12 @@ Create4GPageTablesIa32Pae (
       );\r
   }\r
 \r
+  //\r
+  // Protect the page table by marking the memory used for page table to be\r
+  // read-only.\r
+  //\r
+  EnablePageTableProtection ((UINTN)PageMap, FALSE);\r
+\r
   return (UINTN) PageMap;\r
 }\r
 \r
@@ -180,37 +180,6 @@ IsIa32PaeSupport (
   return Ia32PaeSupport;\r
 }\r
 \r
-/**\r
-  The function will check if Execute Disable Bit is available.\r
-\r
-  @retval TRUE      Execute Disable Bit is available.\r
-  @retval FALSE     Execute Disable Bit is not available.\r
-\r
-**/\r
-BOOLEAN\r
-IsExecuteDisableBitAvailable (\r
-  VOID\r
-  )\r
-{\r
-  UINT32            RegEax;\r
-  UINT32            RegEdx;\r
-  BOOLEAN           Available;\r
-\r
-  Available = FALSE;\r
-  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
-  if (RegEax >= 0x80000001) {\r
-    AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);\r
-    if ((RegEdx & BIT20) != 0) {\r
-      //\r
-      // Bit 20: Execute Disable Bit available.\r
-      //\r
-      Available = TRUE;\r
-    }\r
-  }\r
-\r
-  return Available;\r
-}\r
-\r
 /**\r
   The function will check if page table should be setup or not.\r
 \r
@@ -235,7 +204,11 @@ ToBuildPageTable (
     return TRUE;\r
   }\r
 \r
-  if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) {\r
+  if (PcdGetBool (PcdCpuStackGuard)) {\r
+    return TRUE;\r
+  }\r
+\r
+  if (IsEnableNonExecNeeded ()) {\r
     return TRUE;\r
   }\r
 \r
@@ -273,8 +246,12 @@ HandOffToDxeCore (
   EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;\r
   BOOLEAN                   BuildPageTablesIa32Pae;\r
 \r
+  //\r
+  // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.\r
+  //\r
   if (IsNullDetectionEnabled ()) {\r
     ClearFirst4KPage (HobList.Raw);\r
+    BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);\r
   }\r
 \r
   Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);\r
@@ -310,9 +287,16 @@ HandOffToDxeCore (
     //\r
     // End of PEI phase signal\r
     //\r
+    PERF_EVENT_SIGNAL_BEGIN (gEndOfPeiSignalPpi.Guid);\r
     Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);\r
+    PERF_EVENT_SIGNAL_END (gEndOfPeiSignalPpi.Guid);\r
     ASSERT_EFI_ERROR (Status);\r
 \r
+    //\r
+    // Paging might be already enabled. To avoid conflict configuration,\r
+    // disable paging first anyway.\r
+    //\r
+    AsmWriteCr0 (AsmReadCr0 () & (~BIT31));\r
     AsmWriteCr3 (PageTables);\r
 \r
     //\r
@@ -419,7 +403,7 @@ HandOffToDxeCore (
     BuildPageTablesIa32Pae = ToBuildPageTable ();\r
     if (BuildPageTablesIa32Pae) {\r
       PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);\r
-      if (IsExecuteDisableBitAvailable ()) {\r
+      if (IsEnableNonExecNeeded ()) {\r
         EnableExecuteDisableBit();\r
       }\r
     }\r
@@ -427,10 +411,17 @@ HandOffToDxeCore (
     //\r
     // End of PEI phase signal\r
     //\r
+    PERF_EVENT_SIGNAL_BEGIN (gEndOfPeiSignalPpi.Guid);\r
     Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);\r
+    PERF_EVENT_SIGNAL_END (gEndOfPeiSignalPpi.Guid);\r
     ASSERT_EFI_ERROR (Status);\r
 \r
     if (BuildPageTablesIa32Pae) {\r
+      //\r
+      // Paging might be already enabled. To avoid conflict configuration,\r
+      // disable paging first anyway.\r
+      //\r
+      AsmWriteCr0 (AsmReadCr0 () & (~BIT31));\r
       AsmWriteCr3 (PageTables);\r
       //\r
       // Set Physical Address Extension (bit 5 of CR4).\r