]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/CpuDxe/CpuPageTable.c
UefiCpuPkg/CpuDxe: fix incorrect check of SMM mode
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / CpuPageTable.c
index d4e385139a8b49351bf9e6923bce4bb980b93494..df021798c00988e2668b0ae1cb9b4a9b43e528e8 100644 (file)
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Protocol/MpService.h>\r
 #include <Protocol/SmmBase2.h>\r
+#include <Register/Cpuid.h>\r
+#include <Register/Msr.h>\r
 \r
 #include "CpuDxe.h"\r
 #include "CpuPageTable.h"\r
 \r
+///\r
+/// Paging registers\r
+///\r
+#define CR0_WP                      BIT16\r
+#define CR0_PG                      BIT31\r
+#define CR4_PSE                     BIT4\r
+#define CR4_PAE                     BIT5\r
+\r
 ///\r
 /// Page Table Entry\r
 ///\r
@@ -126,7 +136,14 @@ IsInSmm (
     mSmmBase2->InSmm (mSmmBase2, &InSmm);\r
   }\r
 \r
-  return InSmm;\r
+  //\r
+  // mSmmBase2->InSmm() can only detect if the caller is running in SMRAM\r
+  // or from SMM driver. It cannot tell if the caller is running in SMM mode.\r
+  // Check page table base address to guarantee that because SMM mode willl\r
+  // load its own page table.\r
+  //\r
+  return (InSmm &&\r
+          mPagingContext.ContextData.X64.PageTableBase != (UINT64)AsmReadCr3());\r
 }\r
 \r
 /**\r
@@ -139,8 +156,9 @@ GetCurrentPagingContext (
   IN OUT PAGE_TABLE_LIB_PAGING_CONTEXT     *PagingContext\r
   )\r
 {\r
-  UINT32                         RegEax;\r
-  UINT32                         RegEdx;\r
+  UINT32                          RegEax;\r
+  CPUID_EXTENDED_CPU_SIG_EDX      RegEdx;\r
+  MSR_IA32_EFER_REGISTER          MsrEfer;\r
 \r
   //\r
   // Don't retrieve current paging context from processor if in SMM mode.\r
@@ -152,33 +170,36 @@ GetCurrentPagingContext (
     } else {\r
       mPagingContext.MachineType = IMAGE_FILE_MACHINE_I386;\r
     }\r
-    if ((AsmReadCr0 () & BIT31) != 0) {\r
+    if ((AsmReadCr0 () & CR0_PG) != 0) {\r
       mPagingContext.ContextData.X64.PageTableBase = (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);\r
     } else {\r
       mPagingContext.ContextData.X64.PageTableBase = 0;\r
     }\r
 \r
-    if ((AsmReadCr4 () & BIT4) != 0) {\r
+    if ((AsmReadCr4 () & CR4_PSE) != 0) {\r
       mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PSE;\r
     }\r
-    if ((AsmReadCr4 () & BIT5) != 0) {\r
+    if ((AsmReadCr4 () & CR4_PAE) != 0) {\r
       mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE;\r
     }\r
-    if ((AsmReadCr0 () & BIT16) != 0) {\r
+    if ((AsmReadCr0 () & CR0_WP) != 0) {\r
       mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE;\r
     }\r
 \r
-    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
-    if (RegEax > 0x80000000) {\r
-      AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);\r
-      if ((RegEdx & BIT20) != 0) {\r
+    AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
+    if (RegEax >= CPUID_EXTENDED_CPU_SIG) {\r
+      AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32);\r
+\r
+      if (RegEdx.Bits.NX != 0) {\r
         // XD supported\r
-        if ((AsmReadMsr64 (0xC0000080) & BIT11) != 0) {\r
+        MsrEfer.Uint64 = AsmReadMsr64(MSR_CORE_IA32_EFER);\r
+        if (MsrEfer.Bits.NXE != 0) {\r
           // XD activated\r
           mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED;\r
         }\r
       }\r
-      if ((RegEdx & BIT26) != 0) {\r
+\r
+      if (RegEdx.Bits.Page1GB != 0) {\r
         mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAGE_1G_SUPPORT;\r
       }\r
     }\r
@@ -563,7 +584,7 @@ IsReadOnlyPageWriteProtected (
   // in this driver.\r
   //\r
   if (!IsInSmm ()) {\r
-    return ((AsmReadCr0 () & BIT16) != 0);\r
+    return ((AsmReadCr0 () & CR0_WP) != 0);\r
   }\r
   return FALSE;\r
 }\r
@@ -581,7 +602,7 @@ DisableReadOnlyPageWriteProtect (
   // in this driver.\r
   //\r
   if (!IsInSmm ()) {\r
-    AsmWriteCr0 (AsmReadCr0 () & ~BIT16);\r
+    AsmWriteCr0 (AsmReadCr0 () & ~CR0_WP);\r
   }\r
 }\r
 \r
@@ -598,7 +619,7 @@ EnableReadOnlyPageWriteProtect (
   // in this driver.\r
   //\r
   if (!IsInSmm ()) {\r
-    AsmWriteCr0 (AsmReadCr0 () | BIT16);\r
+    AsmWriteCr0 (AsmReadCr0 () | CR0_WP);\r
   }\r
 }\r
 \r