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:
@@ -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.
|
||||
|
||||
|
Reference in New Issue
Block a user