/** @file\r
Enable SMM profile.\r
\r
-Copyright (c) 2012 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>\r
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
//\r
UINTN mMsrDsAreaSize = SMM_PROFILE_DTS_SIZE;\r
\r
+//\r
+// The flag indicates if execute-disable is supported by processor.\r
+//\r
+BOOLEAN mXdSupported = TRUE;\r
+\r
//\r
// The flag indicates if execute-disable is enabled on processor.\r
//\r
//\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
return ;\r
}\r
\r
-/**\r
- To find FADT in ACPI tables.\r
-\r
- @param AcpiTableGuid The GUID used to find ACPI table in UEFI ConfigurationTable.\r
-\r
- @return FADT table pointer.\r
-**/\r
-EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *\r
-FindAcpiFadtTableByAcpiGuid (\r
- IN EFI_GUID *AcpiTableGuid\r
- )\r
-{\r
- EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
- EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r
- UINTN Index;\r
- UINT32 Data32;\r
- Rsdp = NULL;\r
- Rsdt = NULL;\r
- Fadt = NULL;\r
- //\r
- // found ACPI table RSD_PTR from system table\r
- //\r
- for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {\r
- if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), AcpiTableGuid)) {\r
- //\r
- // A match was found.\r
- //\r
- Rsdp = gST->ConfigurationTable[Index].VendorTable;\r
- break;\r
- }\r
- }\r
-\r
- if (Rsdp == NULL) {\r
- return NULL;\r
- }\r
-\r
- Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress;\r
- if (Rsdt == NULL || Rsdt->Signature != EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {\r
- return NULL;\r
- }\r
-\r
- for (Index = sizeof (EFI_ACPI_DESCRIPTION_HEADER); Index < Rsdt->Length; Index = Index + sizeof (UINT32)) {\r
-\r
- Data32 = *(UINT32 *) ((UINT8 *) Rsdt + Index);\r
- Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) (UINT32 *) (UINTN) Data32;\r
- if (Fadt->Header.Signature == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {\r
- break;\r
- }\r
- }\r
-\r
- if (Fadt == NULL || Fadt->Header.Signature != EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {\r
- return NULL;\r
- }\r
-\r
- return Fadt;\r
-}\r
-\r
-/**\r
- To find FADT in ACPI tables.\r
-\r
- @return FADT table pointer.\r
-**/\r
-EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *\r
-FindAcpiFadtTable (\r
- VOID\r
- )\r
-{\r
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r
-\r
- Fadt = FindAcpiFadtTableByAcpiGuid (&gEfiAcpi20TableGuid);\r
- if (Fadt != NULL) {\r
- return Fadt;\r
- }\r
-\r
- return FindAcpiFadtTableByAcpiGuid (&gEfiAcpi10TableGuid);\r
-}\r
-\r
/**\r
To get system port address of the SMI Command Port in FADT table.\r
\r
{\r
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r
\r
- Fadt = FindAcpiFadtTable ();\r
+ Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) EfiLocateFirstAcpiTable (\r
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE\r
+ );\r
ASSERT (Fadt != NULL);\r
\r
mSmiCommandPort = Fadt->SmiCmd;\r
// Extended CPUID functions are not supported on this processor.\r
//\r
mXdSupported = FALSE;\r
+ PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1);\r
}\r
\r
AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);\r
// Execute Disable Bit feature is not supported on this processor.\r
//\r
mXdSupported = FALSE;\r
+ PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1);\r
}\r
}\r
\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