]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c
UefiCpuPkg/PiSmmCpuDxeSmm: Add paging protection.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmmFuncsArch.c
index 9760373b4740f055f0170cfe5e1fd3f3144c941f..428169831328b1508096fdd8d019451dbc788317 100644 (file)
@@ -14,6 +14,33 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "PiSmmCpuDxeSmm.h"\r
 \r
+extern UINT64 gTaskGateDescriptor;\r
+\r
+EFI_PHYSICAL_ADDRESS                mGdtBuffer;\r
+UINTN                               mGdtBufferSize;\r
+\r
+/**\r
+  Initialize IDT for SMM Stack Guard.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeIDTSmmStackGuard (\r
+  VOID\r
+  )\r
+{\r
+  IA32_IDT_GATE_DESCRIPTOR  *IdtGate;\r
+\r
+  //\r
+  // If SMM Stack Guard feature is enabled, the Page Fault Exception entry in IDT\r
+  // is a Task Gate Descriptor so that when a Page Fault Exception occurs,\r
+  // the processors can use a known good stack in case stack is ran out.\r
+  //\r
+  IdtGate = (IA32_IDT_GATE_DESCRIPTOR *)gcSmiIdtr.Base;\r
+  IdtGate += EXCEPT_IA32_PAGE_FAULT;\r
+  IdtGate->Uint64 = gTaskGateDescriptor;\r
+}\r
+\r
 /**\r
   Initialize Gdt for all processors.\r
   \r
@@ -49,8 +76,10 @@ InitGdt (
     gcSmiGdtr.Limit += (UINT16)(2 * sizeof (IA32_SEGMENT_DESCRIPTOR));\r
 \r
     GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE * 2 + 7) & ~7; // 8 bytes aligned\r
-    GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
+    mGdtBufferSize = GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;\r
+    GdtTssTables = (UINT8*)AllocateCodePages (EFI_SIZE_TO_PAGES (mGdtBufferSize));\r
     ASSERT (GdtTssTables != NULL);\r
+    mGdtBuffer = (UINTN)GdtTssTables;\r
     GdtTableStepSize = GdtTssTableSize;\r
 \r
     for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {\r
@@ -82,8 +111,10 @@ InitGdt (
     // Just use original table, AllocatePage and copy them here to make sure GDTs are covered in page memory.\r
     //\r
     GdtTssTableSize = gcSmiGdtr.Limit + 1;\r
-    GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
+    mGdtBufferSize = GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;\r
+    GdtTssTables = (UINT8*)AllocateCodePages (EFI_SIZE_TO_PAGES (mGdtBufferSize));\r
     ASSERT (GdtTssTables != NULL);\r
+    mGdtBuffer = (UINTN)GdtTssTables;\r
     GdtTableStepSize = GdtTssTableSize;\r
 \r
     for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {\r