]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
UefiCpuPkg/PiSmmCpu: Add Shadow Stack Support for X86 SMM.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / PageTbl.c
index a32b736089ab7eb74cf23df1dca40eef8ad4075c..b734a1ea8c607f5ae30b60959d2e544949d245e4 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Page table manipulation functions for IA-32 processors\r
 \r
-Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2019, 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
@@ -16,6 +16,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "PiSmmCpuDxeSmm.h"\r
 \r
+/**\r
+  Disable CET.\r
+**/\r
+VOID\r
+EFIAPI\r
+DisableCet (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Enable CET.\r
+**/\r
+VOID\r
+EFIAPI\r
+EnableCet (\r
+  VOID\r
+  );\r
+\r
 /**\r
   Create PageTable for SMM use.\r
 \r
@@ -138,6 +156,7 @@ SmiPFHandler (
       }\r
     }\r
     CpuDeadLoop ();\r
+    goto Exit;\r
   }\r
 \r
   //\r
@@ -152,6 +171,7 @@ SmiPFHandler (
         DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextIa32->Esp);\r
       );\r
       CpuDeadLoop ();\r
+      goto Exit;\r
     }\r
 \r
     //\r
@@ -171,6 +191,7 @@ SmiPFHandler (
       }\r
 \r
       CpuDeadLoop ();\r
+      goto Exit;\r
     }\r
 \r
     if (IsSmmCommBufferForbiddenAddress (PFAddress)) {\r
@@ -180,6 +201,7 @@ SmiPFHandler (
         DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip);\r
       );\r
       CpuDeadLoop ();\r
+      goto Exit;\r
     }\r
   }\r
 \r
@@ -212,6 +234,7 @@ SetPageTableAttributes (
   UINT64                *L3PageTable;\r
   BOOLEAN               IsSplitted;\r
   BOOLEAN               PageTableSplitted;\r
+  BOOLEAN               CetEnabled;\r
 \r
   //\r
   // Don't mark page table to read-only if heap guard is enabled.\r
@@ -238,6 +261,13 @@ SetPageTableAttributes (
   // Disable write protection, because we need mark page table to be write protected.\r
   // We need *write* page table memory, to mark itself to be *read only*.\r
   //\r
+  CetEnabled = ((AsmReadCr4() & CR4_CET_ENABLE) != 0) ? TRUE : FALSE;\r
+  if (CetEnabled) {\r
+    //\r
+    // CET must be disabled if WP is disabled.\r
+    //\r
+    DisableCet();\r
+  }\r
   AsmWriteCr0 (AsmReadCr0() & ~CR0_WP);\r
 \r
   do {\r
@@ -277,6 +307,12 @@ SetPageTableAttributes (
   // Enable write protection, after page table updated.\r
   //\r
   AsmWriteCr0 (AsmReadCr0() | CR0_WP);\r
+  if (CetEnabled) {\r
+    //\r
+    // re-enable CET.\r
+    //\r
+    EnableCet();\r
+  }\r
 \r
   return ;\r
 }\r