From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 4E87F81E96 for ; Tue, 22 Nov 2016 21:56:38 -0800 (PST) Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga102.jf.intel.com with ESMTP; 22 Nov 2016 21:56:37 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,684,1473145200"; d="scan'208";a="34700967" Received: from jyao1-mobl.ccr.corp.intel.com ([10.239.192.75]) by fmsmga006.fm.intel.com with ESMTP; 22 Nov 2016 21:56:36 -0800 From: Jiewen Yao To: edk2-devel@lists.01.org Cc: Laszlo Ersek , Jeff Fan , Michael D Kinney Date: Wed, 23 Nov 2016 13:56:34 +0800 Message-Id: <1479880594-29052-1-git-send-email-jiewen.yao@intel.com> X-Mailer: git-send-email 2.7.4.windows.1 Subject: [PATCH V2] UefiCpuPkg/PiSmmCpu: Correct exception message. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Nov 2016 05:56:38 -0000 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 Cc: Jeff Fan Cc: Michael D Kinney Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao --- UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c | 38 ++++++++++++++++++-- UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h | 9 +++++ UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c | 36 ++++++++++++++++--- 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c index 5033bc5..39e6c9a 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,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", SystemContext.SystemContextIa32->ExceptionData)); + 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 (); } 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..6eada5c 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,38 @@ 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(\n", 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 + )); + 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 (); } -- 2.7.4.windows.1