summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
diff options
context:
space:
mode:
authorJian J Wang <jian.j.wang@intel.com>2018-08-20 11:35:58 +0800
committerJian J Wang <jian.j.wang@intel.com>2018-08-30 07:22:30 +0800
commit09afd9a42a7ff719bcb5b464a2b2dea7eb3e5e7b (patch)
treebe5b00f1080d6fc786c8ecf9da206bb0152da729 /UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
parentdcc026217fdc363f55c217039fc43d344f69fed6 (diff)
downloadedk2-09afd9a42a7ff719bcb5b464a2b2dea7eb3e5e7b.tar.gz
edk2-09afd9a42a7ff719bcb5b464a2b2dea7eb3e5e7b.tar.bz2
edk2-09afd9a42a7ff719bcb5b464a2b2dea7eb3e5e7b.zip
UefiCpuPkg/PiSmmCpuDxeSmm: implement non-stop mode for SMM
Since SMM profile feature has already implemented non-stop mode if #PF occurred, this patch just makes use of the existing implementation to accommodate heap guard and NULL pointer detection feature. Cc: Eric Dong <eric.dong@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang <jian.j.wang@intel.com> Reviewed-by: Eric Dong <eric.dong@intel.com> Acked-by: Laszlo Ersek <lersek@redhat.com>
Diffstat (limited to 'UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c')
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
index b4fe0bc23b..a743cf64f9 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
@@ -52,6 +52,11 @@ BOOLEAN mBtsSupported = TRUE;
BOOLEAN mSmmProfileStart = FALSE;
//
+// The flag indicates if #DB will be setup in #PF handler.
+//
+BOOLEAN mSetupDebugTrap = FALSE;
+
+//
// Record the page fault exception count for one instruction execution.
//
UINTN *mPFEntryCount;
@@ -229,7 +234,9 @@ DebugExceptionHandler (
UINTN CpuIndex;
UINTN PFEntry;
- if (!mSmmProfileStart) {
+ if (!mSmmProfileStart &&
+ !HEAP_GUARD_NONSTOP_MODE &&
+ !NULL_DETECTION_NONSTOP_MODE) {
return;
}
CpuIndex = GetCpuIndex ();
@@ -1174,7 +1181,9 @@ InitSmmProfile (
//
// Skip SMM profile initialization if feature is disabled
//
- if (!FeaturePcdGet (PcdCpuSmmProfileEnable)) {
+ if (!FeaturePcdGet (PcdCpuSmmProfileEnable) &&
+ !HEAP_GUARD_NONSTOP_MODE &&
+ !NULL_DETECTION_NONSTOP_MODE) {
return;
}
@@ -1187,6 +1196,11 @@ InitSmmProfile (
// Initialize profile IDT.
//
InitIdtr ();
+
+ //
+ // Tell #PF handler to prepare a #DB subsequently.
+ //
+ mSetupDebugTrap = TRUE;
}
/**
@@ -1295,6 +1309,46 @@ RestorePageTableBelow4G (
}
/**
+ Handler for Page Fault triggered by Guard page.
+
+ @param ErrorCode The Error code of exception.
+
+**/
+VOID
+GuardPagePFHandler (
+ UINTN ErrorCode
+ )
+{
+ UINT64 *PageTable;
+ UINT64 PFAddress;
+ UINT64 RestoreAddress;
+ UINTN RestorePageNumber;
+ UINTN CpuIndex;
+
+ PageTable = (UINT64 *)AsmReadCr3 ();
+ PFAddress = AsmReadCr2 ();
+ CpuIndex = GetCpuIndex ();
+
+ //
+ // Memory operation cross pages, like "rep mov" instruction, will cause
+ // infinite loop between this and Debug Trap handler. We have to make sure
+ // that current page and the page followed are both in PRESENT state.
+ //
+ RestorePageNumber = 2;
+ RestoreAddress = PFAddress;
+ while (RestorePageNumber > 0) {
+ RestorePageTableBelow4G (PageTable, RestoreAddress, CpuIndex, ErrorCode);
+ RestoreAddress += EFI_PAGE_SIZE;
+ RestorePageNumber--;
+ }
+
+ //
+ // Flush TLB
+ //
+ CpuFlushTlb ();
+}
+
+/**
The Page fault handler to save SMM profile data.
@param Rip The RIP when exception happens.