UefiCpuPkg/PiSmmCpu: Correct exception message.

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>
This commit is contained in:
Jiewen Yao 2016-11-22 15:05:11 +08:00
parent 1cbd833089
commit 7fa1376c5c
3 changed files with 77 additions and 7 deletions

View File

@ -91,6 +91,8 @@ SmiPFHandler (
)
{
UINTN PFAddress;
UINTN GuardPageAddress;
UINTN CpuIndex;
ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
@ -98,10 +100,40 @@ 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"));
} else {
DEBUG ((DEBUG_ERROR, "SMM exception data - 0x%x(", SystemContext.SystemContextIa32->ExceptionData));
DEBUG ((DEBUG_ERROR, "I:%x, R:%x, U:%x, W:%x, P:%x",
(SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0,
(SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_RSVD) != 0,
(SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_US) != 0,
(SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_WR) != 0,
(SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_P) != 0
));
DEBUG ((DEBUG_ERROR, ")\n"));
if ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0) {
DEBUG ((DEBUG_ERROR, "SMM exception at execution (0x%x)\n", PFAddress));
DEBUG_CODE (
DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextIa32->Esp);
);
} else {
DEBUG ((DEBUG_ERROR, "SMM exception at access (0x%x)\n", PFAddress));
DEBUG_CODE (
DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextIa32->Eip);
);
}
}
CpuDeadLoop ();
}

View File

@ -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.
//

View File

@ -804,6 +804,8 @@ SmiPFHandler (
)
{
UINTN PFAddress;
UINTN GuardPageAddress;
UINTN CpuIndex;
ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
@ -817,12 +819,39 @@ 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"));
} else {
DEBUG ((DEBUG_ERROR, "SMM exception data - 0x%lx(", SystemContext.SystemContextX64->ExceptionData));
DEBUG ((DEBUG_ERROR, "I:%x, R:%x, U:%x, W:%x, P:%x",
(SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0,
(SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_RSVD) != 0,
(SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_US) != 0,
(SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_WR) != 0,
(SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_P) != 0
));
DEBUG ((DEBUG_ERROR, ")\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 access (0x%lx)\n", PFAddress));
DEBUG_CODE (
DumpModuleInfoByIp ((UINTN)SystemContext.SystemContextX64->Rip);
);
}
}
CpuDeadLoop ();
}