]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/PiSmmCpuDxeSmm:Fix PF issue caused by smm page table code
authorTan, Dun <dun.tan@intel.com>
Tue, 3 Jan 2023 05:56:17 +0000 (13:56 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Tue, 3 Jan 2023 06:41:11 +0000 (06:41 +0000)
When setting new page table pool to RO, only disable/enable WP when
Cr0.WP has been set to 1 to fix potential PF caused by b822be1a20
(UefiCpuPkg/PiSmmCpuDxeSmm: Introduce page table pool mechanism).
With previous code, if someone want to modify the page table and
Cr0.WP has been cleared before modify page table, Cr0.WP may be set
to 1 again since new pool may be generated during this process
Then PF fault may happens.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c

index 4bb23f692096962e8595db7ff218ab8ce4caad7b..834a756061da80b26ce2086740c8689fd6946d2f 100644 (file)
@@ -67,8 +67,10 @@ InitializePageTablePool (
   IN UINTN  PoolPages\r
   )\r
 {\r
-  VOID     *Buffer;\r
-  BOOLEAN  CetEnabled;\r
+  VOID      *Buffer;\r
+  BOOLEAN   CetEnabled;\r
+  BOOLEAN   WpEnabled;\r
+  IA32_CR0  Cr0;\r
 \r
   //\r
   // Always reserve at least PAGE_TABLE_POOL_UNIT_PAGES, including one page for\r
@@ -106,21 +108,32 @@ InitializePageTablePool (
   //\r
   if (mIsReadOnlyPageTable) {\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
+    Cr0.UintN  = AsmReadCr0 ();\r
+    WpEnabled  = (Cr0.Bits.WP != 0) ? TRUE : FALSE;\r
+    if (WpEnabled) {\r
+      if (CetEnabled) {\r
+        //\r
+        // CET must be disabled if WP is disabled. Disable CET before clearing CR0.WP.\r
+        //\r
+        DisableCet ();\r
+      }\r
+\r
+      Cr0.Bits.WP = 0;\r
+      AsmWriteCr0 (Cr0.UintN);\r
     }\r
 \r
-    AsmWriteCr0 (AsmReadCr0 () & ~CR0_WP);\r
     SmmSetMemoryAttributes ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, EFI_PAGES_TO_SIZE (PoolPages), EFI_MEMORY_RO);\r
-    AsmWriteCr0 (AsmReadCr0 () | CR0_WP);\r
-    if (CetEnabled) {\r
-      //\r
-      // re-enable CET.\r
-      //\r
-      EnableCet ();\r
+    if (WpEnabled) {\r
+      Cr0.UintN   = AsmReadCr0 ();\r
+      Cr0.Bits.WP = 1;\r
+      AsmWriteCr0 (Cr0.UintN);\r
+\r
+      if (CetEnabled) {\r
+        //\r
+        // re-enable CET.\r
+        //\r
+        EnableCet ();\r
+      }\r
     }\r
   }\r
 \r