]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/PiSmmCpu: Correct exception message.
authorJiewen Yao <jiewen.yao@intel.com>
Tue, 22 Nov 2016 07:05:11 +0000 (15:05 +0800)
committerJiewen Yao <jiewen.yao@intel.com>
Thu, 24 Nov 2016 02:51:16 +0000 (10:51 +0800)
This patch fixes the first part of
https://bugzilla.tianocore.org/show_bug.cgi?id=242

Previously, when SMM exception happens, "stack overflow" is misreported.
This patch checked the PF address to see it is stack overflow, or
it is caused by SMM page protection.

It dumps exception data, PF address and the module trigger the issue.

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c

index 5033bc50d76a9854660d3724e3c97bda77aec57d..ba79477e645dab687ad560fe2cbde46464e6aa4e 100644 (file)
@@ -91,6 +91,8 @@ SmiPFHandler (
   )\r
 {\r
   UINTN             PFAddress;\r
+  UINTN             GuardPageAddress;\r
+  UINTN             CpuIndex;\r
 \r
   ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);\r
 \r
@@ -98,10 +100,40 @@ SmiPFHandler (
 \r
   PFAddress = AsmReadCr2 ();\r
 \r
-  if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&\r
-      (PFAddress >= mCpuHotPlugData.SmrrBase) &&\r
+  //\r
+  // If a page fault occurs in SMRAM range, it might be in a SMM stack guard page,\r
+  // or SMM page protection violation.\r
+  //\r
+  if ((PFAddress >= mCpuHotPlugData.SmrrBase) &&\r
       (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) {\r
-    DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n"));\r
+    CpuIndex = GetCpuIndex ();\r
+    GuardPageAddress = (mSmmStackArrayBase + EFI_PAGE_SIZE + CpuIndex * mSmmStackSize);\r
+    if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&\r
+        (PFAddress >= GuardPageAddress) &&\r
+        (PFAddress < (GuardPageAddress + EFI_PAGE_SIZE))) {\r
+      DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n"));\r
+    } else {\r
+      DEBUG ((DEBUG_ERROR, "SMM exception data - 0x%x(", SystemContext.SystemContextIa32->ExceptionData));\r
+      DEBUG ((DEBUG_ERROR, "I:%x, R:%x, U:%x, W:%x, P:%x",\r
+        (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0,\r
+        (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_RSVD) != 0,\r
+        (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_US) != 0,\r
+        (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_WR) != 0,\r
+        (SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_P) != 0\r
+        ));\r
+      DEBUG ((DEBUG_ERROR, ")\n"));\r
+      if ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0) {\r
+        DEBUG ((DEBUG_ERROR, "SMM exception at execution (0x%x)\n", PFAddress));\r
+        DEBUG_CODE (\r
+          DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextIa32->Esp);\r
+        );\r
+      } else {\r
+        DEBUG ((DEBUG_ERROR, "SMM exception at access (0x%x)\n", PFAddress));\r
+        DEBUG_CODE (\r
+          DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip);\r
+        );\r
+      }\r
+    }\r
     CpuDeadLoop ();\r
   }\r
 \r
index b6fb5cf34b23e20d388e51bfa2c0a04bb7a44c85..04a3dfb2e85764ea9dca99d83f1e105aea5812ef 100644 (file)
@@ -105,6 +105,15 @@ InitPaging (
   VOID\r
   );\r
 \r
+/**\r
+  Get CPU Index from APIC ID.\r
+\r
+**/\r
+UINTN\r
+GetCpuIndex (\r
+  VOID\r
+  );\r
+\r
 //\r
 // The flag indicates if execute-disable is supported by processor.\r
 //\r
index 531e1882150de97c49e195660e1a01b4dae94652..7237e57e7e404e33498bf1566724b63fdc31b782 100644 (file)
@@ -804,6 +804,8 @@ SmiPFHandler (
   )\r
 {\r
   UINTN             PFAddress;\r
+  UINTN             GuardPageAddress;\r
+  UINTN             CpuIndex;\r
 \r
   ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);\r
 \r
@@ -817,12 +819,39 @@ SmiPFHandler (
   }\r
 \r
   //\r
-  // If a page fault occurs in SMRAM range, it should be in a SMM stack guard page.\r
+  // If a page fault occurs in SMRAM range, it might be in a SMM stack guard page,\r
+  // or SMM page protection violation.\r
   //\r
-  if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&\r
-      (PFAddress >= mCpuHotPlugData.SmrrBase) &&\r
+  if ((PFAddress >= mCpuHotPlugData.SmrrBase) &&\r
       (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) {\r
-    DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n"));\r
+    CpuIndex = GetCpuIndex ();\r
+    GuardPageAddress = (mSmmStackArrayBase + EFI_PAGE_SIZE + CpuIndex * mSmmStackSize);\r
+    if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&\r
+        (PFAddress >= GuardPageAddress) &&\r
+        (PFAddress < (GuardPageAddress + EFI_PAGE_SIZE))) {\r
+      DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n"));\r
+    } else {\r
+      DEBUG ((DEBUG_ERROR, "SMM exception data - 0x%lx(", SystemContext.SystemContextX64->ExceptionData));\r
+      DEBUG ((DEBUG_ERROR, "I:%x, R:%x, U:%x, W:%x, P:%x",\r
+        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0,\r
+        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_RSVD) != 0,\r
+        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_US) != 0,\r
+        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_WR) != 0,\r
+        (SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_P) != 0\r
+        ));\r
+      DEBUG ((DEBUG_ERROR, ")\n"));\r
+      if ((SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0) {\r
+        DEBUG ((DEBUG_ERROR, "SMM exception at execution (0x%lx)\n", PFAddress));\r
+        DEBUG_CODE (\r
+          DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextX64->Rsp);\r
+        );\r
+      } else {\r
+        DEBUG ((DEBUG_ERROR, "SMM exception at access (0x%lx)\n", PFAddress));\r
+        DEBUG_CODE (\r
+          DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextX64->Rip);\r
+        );\r
+      }\r
+    }\r
     CpuDeadLoop ();\r
   }\r
 \r