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.

Cc: Laszlo Ersek <[email protected]>
Cc: Jeff Fan <[email protected]>
Cc: Michael D Kinney <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <[email protected]>
---
 UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 28 +++++++++++++++++---
 UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h   |  9 +++++++
 UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c  | 27 ++++++++++++++++---
 3 files changed, 57 insertions(+), 7 deletions(-)

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c 
b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
index 5033bc5..feca142 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
@@ -91,6 +91,8 @@ SmiPFHandler (
   )
 {
   UINTN             PFAddress;
+  UINTN             GuardPageAddress;
+  UINTN             CpuIndex;
 
   ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
 
@@ -98,10 +100,30 @@ SmiPFHandler (
 
   PFAddress = AsmReadCr2 ();
 
-  if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
-      (PFAddress >= mCpuHotPlugData.SmrrBase) &&
+  //
+  // If a page fault occurs in SMRAM range, it might be in a SMM stack guard 
page,
+  // or SMM page protection violation.
+  //
+  if ((PFAddress >= mCpuHotPlugData.SmrrBase) &&
       (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) {
-    DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n"));
+    CpuIndex = GetCpuIndex ();
+    GuardPageAddress = (mSmmStackArrayBase + EFI_PAGE_SIZE + CpuIndex * 
mSmmStackSize);
+    if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
+        (PFAddress >= GuardPageAddress) &&
+        (PFAddress < (GuardPageAddress + EFI_PAGE_SIZE))) {
+      DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n"));
+    }
+    if ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0) 
{
+      DEBUG ((DEBUG_ERROR, "SMM exception at execution (0x%lx)\n", PFAddress));
+      DEBUG_CODE (
+        DumpModuleInfoByIp (*(UINTN 
*)(UINTN)SystemContext.SystemContextIa32->Esp);
+      );
+    } else {
+      DEBUG ((DEBUG_ERROR, "SMM exception at write (0x%lx)\n", PFAddress));
+      DEBUG_CODE (
+        DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip);
+      );
+    }
     CpuDeadLoop ();
   }
 
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h 
b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
index b6fb5cf..04a3dfb 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
@@ -105,6 +105,15 @@ InitPaging (
   VOID
   );
 
+/**
+  Get CPU Index from APIC ID.
+
+**/
+UINTN
+GetCpuIndex (
+  VOID
+  );
+
 //
 // The flag indicates if execute-disable is supported by processor.
 //
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c 
b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
index 531e188..ec8eab7 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
@@ -804,6 +804,8 @@ SmiPFHandler (
   )
 {
   UINTN             PFAddress;
+  UINTN             GuardPageAddress;
+  UINTN             CpuIndex;
 
   ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
 
@@ -817,12 +819,29 @@ SmiPFHandler (
   }
 
   //
-  // If a page fault occurs in SMRAM range, it should be in a SMM stack guard 
page.
+  // If a page fault occurs in SMRAM range, it might be in a SMM stack guard 
page,
+  // or SMM page protection violation.
   //
-  if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
-      (PFAddress >= mCpuHotPlugData.SmrrBase) &&
+  if ((PFAddress >= mCpuHotPlugData.SmrrBase) &&
       (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) {
-    DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n"));
+    CpuIndex = GetCpuIndex ();
+    GuardPageAddress = (mSmmStackArrayBase + EFI_PAGE_SIZE + CpuIndex * 
mSmmStackSize);
+    if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
+        (PFAddress >= GuardPageAddress) &&
+        (PFAddress < (GuardPageAddress + EFI_PAGE_SIZE))) {
+      DEBUG ((DEBUG_ERROR, "SMM stack overflow!\n"));
+    }
+    if ((SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0) {
+      DEBUG ((DEBUG_ERROR, "SMM exception at execution (0x%lx)\n", PFAddress));
+      DEBUG_CODE (
+        DumpModuleInfoByIp (*(UINTN 
*)(UINTN)SystemContext.SystemContextX64->Rsp);
+      );
+    } else {
+      DEBUG ((DEBUG_ERROR, "SMM exception at write (0x%lx)\n", PFAddress));
+      DEBUG_CODE (
+        DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextX64->Rip);
+      );
+    }
     CpuDeadLoop ();
   }
 
-- 
2.7.4.windows.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to