]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
MdeModulePkg/DxeIpl: Enable paging for Stack Guard
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / Ia32 / DxeLoadFunc.c
index c1ff4b7e64340526485ed7d6467f15834e5c70f3..441096ad0f5e24a5f61a52010ac1d8e1a0a5aef6 100644 (file)
@@ -2,6 +2,8 @@
   Ia32-specific functionality for DxeLoad.\r
 \r
 Copyright (c) 2006 - 2015, 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
@@ -82,6 +84,12 @@ Create4GPageTablesIa32Pae (
   PAGE_TABLE_ENTRY                              *PageDirectoryEntry;\r
   UINTN                                         TotalPagesNum;\r
   UINTN                                         PageAddress;\r
+  UINT64                                        AddressEncMask;\r
+\r
+  //\r
+  // Make sure AddressEncMask is contained to smallest supported address field\r
+  //\r
+  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;\r
 \r
   PhysicalAddressBits = 32;\r
 \r
@@ -111,11 +119,13 @@ Create4GPageTablesIa32Pae (
     //\r
     // Fill in a Page Directory Pointer Entries\r
     //\r
-    PageDirectoryPointerEntry->Uint64 = (UINT64) (UINTN) PageDirectoryEntry;\r
+    PageDirectoryPointerEntry->Uint64 = (UINT64) (UINTN) PageDirectoryEntry | AddressEncMask;\r
     PageDirectoryPointerEntry->Bits.Present = 1;\r
 \r
     for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) {\r
-      if ((PhysicalAddress < StackBase + StackSize) && ((PhysicalAddress + SIZE_2MB) > StackBase)) {\r
+      if ((IsNullDetectionEnabled () && PhysicalAddress == 0)\r
+          || ((PhysicalAddress < StackBase + StackSize)\r
+              && ((PhysicalAddress + SIZE_2MB) > StackBase))) {\r
         //\r
         // Need to split this 2M page that covers stack range.\r
         //\r
@@ -124,7 +134,7 @@ Create4GPageTablesIa32Pae (
         //\r
         // Fill in the Page Directory entries\r
         //\r
-        PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress;\r
+        PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress | AddressEncMask;\r
         PageDirectoryEntry->Bits.ReadWrite = 1;\r
         PageDirectoryEntry->Bits.Present = 1;\r
         PageDirectoryEntry->Bits.MustBe1 = 1;\r
@@ -201,6 +211,41 @@ IsExecuteDisableBitAvailable (
   return Available;\r
 }\r
 \r
+/**\r
+  The function will check if page table should be setup or not.\r
+\r
+  @retval TRUE      Page table should be created.\r
+  @retval FALSE     Page table should not be created.\r
+\r
+**/\r
+BOOLEAN\r
+ToBuildPageTable (\r
+  VOID\r
+  )\r
+{\r
+  if (!IsIa32PaeSupport ()) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (IsNullDetectionEnabled ()) {\r
+    return TRUE;\r
+  }\r
+\r
+  if (PcdGet8 (PcdHeapGuardPropertyMask) != 0) {\r
+    return TRUE;\r
+  }\r
+\r
+  if (PcdGetBool (PcdCpuStackGuard)) {\r
+    return TRUE;\r
+  }\r
+\r
+  if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
 /**\r
    Transfers control to DxeCore.\r
 \r
@@ -232,6 +277,10 @@ HandOffToDxeCore (
   EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;\r
   BOOLEAN                   BuildPageTablesIa32Pae;\r
 \r
+  if (IsNullDetectionEnabled ()) {\r
+    ClearFirst4KPage (HobList.Raw);\r
+  }\r
+\r
   Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
@@ -280,7 +329,7 @@ HandOffToDxeCore (
     Status = PeiServicesAllocatePages (\r
                EfiBootServicesData,\r
                EFI_SIZE_TO_PAGES(sizeof (X64_IDT_TABLE) + SizeOfTemplate * IDT_ENTRY_COUNT),\r
-               (EFI_PHYSICAL_ADDRESS *) &IdtTableForX64\r
+               &VectorAddress\r
                );\r
     ASSERT_EFI_ERROR (Status);\r
 \r
@@ -288,6 +337,7 @@ HandOffToDxeCore (
     // Store EFI_PEI_SERVICES** in the 4 bytes immediately preceding IDT to avoid that\r
     // it may not be gotten correctly after IDT register is re-written.\r
     //\r
+    IdtTableForX64 = (X64_IDT_TABLE *) (UINTN) VectorAddress;\r
     IdtTableForX64->PeiService = GetPeiServicesTablePointer ();\r
 \r
     VectorAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) (IdtTableForX64 + 1);\r
@@ -317,6 +367,14 @@ HandOffToDxeCore (
 \r
     AsmWriteIdtr (&gLidtDescriptor);\r
 \r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "%a() Stack Base: 0x%lx, Stack Size: 0x%x\n",\r
+      __FUNCTION__,\r
+      BaseOfStack,\r
+      STACK_SIZE\r
+      ));\r
+\r
     //\r
     // Go to Long Mode and transfer control to DxeCore.\r
     // Interrupts will not get turned on until the CPU AP is loaded.\r
@@ -361,10 +419,13 @@ HandOffToDxeCore (
     TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT;\r
     TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
 \r
-    BuildPageTablesIa32Pae = (BOOLEAN) (PcdGetBool (PcdSetNxForStack) && IsIa32PaeSupport () && IsExecuteDisableBitAvailable ());\r
+    PageTables = 0;\r
+    BuildPageTablesIa32Pae = ToBuildPageTable ();\r
     if (BuildPageTablesIa32Pae) {\r
       PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);\r
-      EnableExecuteDisableBit ();\r
+      if (IsExecuteDisableBitAvailable ()) {\r
+        EnableExecuteDisableBit();\r
+      }\r
     }\r
 \r
     //\r
@@ -386,6 +447,14 @@ HandOffToDxeCore (
     //\r
     UpdateStackHob (BaseOfStack, STACK_SIZE);\r
 \r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "%a() Stack Base: 0x%lx, Stack Size: 0x%x\n",\r
+      __FUNCTION__,\r
+      BaseOfStack,\r
+      STACK_SIZE\r
+      ));\r
+\r
     //\r
     // Transfer the control to the entry point of DxeCore.\r
     //\r