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>
This commit is contained in:
Jian J Wang
2018-08-20 11:35:58 +08:00
parent dcc026217f
commit 09afd9a42a
6 changed files with 137 additions and 31 deletions

View File

@@ -51,6 +51,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.
//
@@ -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;
}
/**
@@ -1294,6 +1308,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.