//\r
BOOLEAN mSmmProfileStart = FALSE;\r
\r
+//\r
+// The flag indicates if #DB will be setup in #PF handler.\r
+//\r
+BOOLEAN mSetupDebugTrap = FALSE;\r
+\r
//\r
// Record the page fault exception count for one instruction execution.\r
//\r
UINTN CpuIndex;\r
UINTN PFEntry;\r
\r
- if (!mSmmProfileStart) {\r
+ if (!mSmmProfileStart &&\r
+ !HEAP_GUARD_NONSTOP_MODE &&\r
+ !NULL_DETECTION_NONSTOP_MODE) {\r
return;\r
}\r
CpuIndex = GetCpuIndex ();\r
//\r
// Skip SMM profile initialization if feature is disabled\r
//\r
- if (!FeaturePcdGet (PcdCpuSmmProfileEnable)) {\r
+ if (!FeaturePcdGet (PcdCpuSmmProfileEnable) &&\r
+ !HEAP_GUARD_NONSTOP_MODE &&\r
+ !NULL_DETECTION_NONSTOP_MODE) {\r
return;\r
}\r
\r
// Initialize profile IDT.\r
//\r
InitIdtr ();\r
+\r
+ //\r
+ // Tell #PF handler to prepare a #DB subsequently.\r
+ //\r
+ mSetupDebugTrap = TRUE;\r
}\r
\r
/**\r
}\r
}\r
\r
+/**\r
+ Handler for Page Fault triggered by Guard page.\r
+\r
+ @param ErrorCode The Error code of exception.\r
+\r
+**/\r
+VOID\r
+GuardPagePFHandler (\r
+ UINTN ErrorCode\r
+ )\r
+{\r
+ UINT64 *PageTable;\r
+ UINT64 PFAddress;\r
+ UINT64 RestoreAddress;\r
+ UINTN RestorePageNumber;\r
+ UINTN CpuIndex;\r
+\r
+ PageTable = (UINT64 *)AsmReadCr3 ();\r
+ PFAddress = AsmReadCr2 ();\r
+ CpuIndex = GetCpuIndex ();\r
+\r
+ //\r
+ // Memory operation cross pages, like "rep mov" instruction, will cause\r
+ // infinite loop between this and Debug Trap handler. We have to make sure\r
+ // that current page and the page followed are both in PRESENT state.\r
+ //\r
+ RestorePageNumber = 2;\r
+ RestoreAddress = PFAddress;\r
+ while (RestorePageNumber > 0) {\r
+ RestorePageTableBelow4G (PageTable, RestoreAddress, CpuIndex, ErrorCode);\r
+ RestoreAddress += EFI_PAGE_SIZE;\r
+ RestorePageNumber--;\r
+ }\r
+\r
+ //\r
+ // Flush TLB\r
+ //\r
+ CpuFlushTlb ();\r
+}\r
+\r
/**\r
The Page fault handler to save SMM profile data.\r
\r