/** @file\r
Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.\r
\r
-Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2019, 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
UINTN mSmmStackArrayEnd;\r
UINTN mSmmStackSize;\r
\r
+UINTN mSmmShadowStackSize;\r
+BOOLEAN mCetSupported = TRUE;\r
+\r
UINTN mMaxNumberOfCpus = 1;\r
UINTN mNumberOfCpus = 1;\r
\r
PatchInstructionX86 (gPatchSmmCr0, mSmmCr0, 4);\r
PatchInstructionX86 (gPatchSmmCr3, AsmReadCr3 (), 4);\r
mSmmCr4 = (UINT32)AsmReadCr4 ();\r
- PatchInstructionX86 (gPatchSmmCr4, mSmmCr4, 4);\r
+ PatchInstructionX86 (gPatchSmmCr4, mSmmCr4 & (~CR4_CET_ENABLE), 4);\r
\r
//\r
// Patch GDTR for SMM base relocation\r
UINT8 *Stacks;\r
VOID *Registration;\r
UINT32 RegEax;\r
+ UINT32 RegEbx;\r
+ UINT32 RegEcx;\r
UINT32 RegEdx;\r
UINTN FamilyId;\r
UINTN ModelId;\r
}\r
}\r
\r
+ DEBUG ((DEBUG_INFO, "PcdControlFlowEnforcementPropertyMask = %d\n", PcdGet32 (PcdControlFlowEnforcementPropertyMask)));\r
+ if (PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) {\r
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
+ if (RegEax > CPUID_EXTENDED_FUNCTION) {\r
+ AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, NULL, NULL, &RegEcx, &RegEdx);\r
+ DEBUG ((DEBUG_INFO, "CPUID[7/0] ECX - 0x%08x\n", RegEcx));\r
+ DEBUG ((DEBUG_INFO, " CET_SS - 0x%08x\n", RegEcx & CPUID_CET_SS));\r
+ DEBUG ((DEBUG_INFO, " CET_IBT - 0x%08x\n", RegEdx & CPUID_CET_IBT));\r
+ if ((RegEcx & CPUID_CET_SS) == 0) {\r
+ mCetSupported = FALSE;\r
+ PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1);\r
+ }\r
+ if (mCetSupported) {\r
+ AsmCpuidEx (CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, NULL, &RegEbx, &RegEcx, NULL);\r
+ DEBUG ((DEBUG_INFO, "CPUID[D/1] EBX - 0x%08x, ECX - 0x%08x\n", RegEbx, RegEcx));\r
+ AsmCpuidEx (CPUID_EXTENDED_STATE, 11, &RegEax, NULL, &RegEcx, NULL);\r
+ DEBUG ((DEBUG_INFO, "CPUID[D/11] EAX - 0x%08x, ECX - 0x%08x\n", RegEax, RegEcx));\r
+ AsmCpuidEx(CPUID_EXTENDED_STATE, 12, &RegEax, NULL, &RegEcx, NULL);\r
+ DEBUG ((DEBUG_INFO, "CPUID[D/12] EAX - 0x%08x, ECX - 0x%08x\n", RegEax, RegEcx));\r
+ }\r
+ }\r
+ } else {\r
+ mCetSupported = FALSE;\r
+ PatchInstructionX86 (mPatchCetSupported, mCetSupported, 1);\r
+ }\r
+\r
//\r
// Compute tile size of buffer required to hold the CPU SMRAM Save State Map, extra CPU\r
// specific context start starts at SMBASE + SMM_PSD_OFFSET, and the SMI entry point.\r
//\r
// Allocate SMI stacks for all processors.\r
//\r
+ mSmmStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize)));\r
if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
//\r
// 2 more pages is allocated for each processor.\r
// | | | |\r
// |<-------------- Processor 0 -------------->| |<-------------- Processor n -------------->|\r
//\r
- mSmmStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize)) + 2);\r
- Stacks = (UINT8 *) AllocatePages (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize)) + 2));\r
- ASSERT (Stacks != NULL);\r
- mSmmStackArrayBase = (UINTN)Stacks;\r
- mSmmStackArrayEnd = mSmmStackArrayBase + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * mSmmStackSize - 1;\r
- } else {\r
- mSmmStackSize = PcdGet32 (PcdCpuSmmStackSize);\r
- Stacks = (UINT8 *) AllocatePages (EFI_SIZE_TO_PAGES (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * mSmmStackSize));\r
- ASSERT (Stacks != NULL);\r
+ mSmmStackSize += EFI_PAGES_TO_SIZE (2);\r
+ }\r
+\r
+ mSmmShadowStackSize = 0;\r
+ if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {\r
+ //\r
+ // Append Shadow Stack after normal stack\r
+ //\r
+ // |= Stacks\r
+ // +--------------------------------------------------+---------------------------------------------------------------+\r
+ // | Known Good Stack | Guard Page | SMM Stack | Known Good Shadow Stack | Guard Page | SMM Shadow Stack |\r
+ // +--------------------------------------------------+---------------------------------------------------------------+\r
+ // | |PcdCpuSmmStackSize| |PcdCpuSmmShadowStackSize|\r
+ // |<---------------- mSmmStackSize ----------------->|<--------------------- mSmmShadowStackSize ------------------->|\r
+ // | |\r
+ // |<-------------------------------------------- Processor N ------------------------------------------------------->|\r
+ //\r
+ mSmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize)));\r
+ if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
+ mSmmShadowStackSize += EFI_PAGES_TO_SIZE (2);\r
+ }\r
+ }\r
+\r
+ Stacks = (UINT8 *) AllocatePages (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (EFI_SIZE_TO_PAGES (mSmmStackSize + mSmmShadowStackSize)));\r
+ ASSERT (Stacks != NULL);\r
+ mSmmStackArrayBase = (UINTN)Stacks;\r
+ mSmmStackArrayEnd = mSmmStackArrayBase + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (mSmmStackSize + mSmmShadowStackSize) - 1;\r
+\r
+ DEBUG ((DEBUG_INFO, "Stacks - 0x%x\n", Stacks));\r
+ DEBUG ((DEBUG_INFO, "mSmmStackSize - 0x%x\n", mSmmStackSize));\r
+ DEBUG ((DEBUG_INFO, "PcdCpuSmmStackGuard - 0x%x\n", FeaturePcdGet (PcdCpuSmmStackGuard)));\r
+ if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {\r
+ DEBUG ((DEBUG_INFO, "mSmmShadowStackSize - 0x%x\n", mSmmShadowStackSize));\r
}\r
\r
//\r
//\r
// Initialize MP globals\r
//\r
- Cr3 = InitializeMpServiceData (Stacks, mSmmStackSize);\r
+ Cr3 = InitializeMpServiceData (Stacks, mSmmStackSize, mSmmShadowStackSize);\r
+\r
+ if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {\r
+ for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {\r
+ SetShadowStack (\r
+ Cr3,\r
+ (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + (mSmmStackSize + mSmmShadowStackSize) * Index,\r
+ mSmmShadowStackSize\r
+ );\r
+ if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
+ SetNotPresentPage (\r
+ Cr3,\r
+ (EFI_PHYSICAL_ADDRESS)(UINTN)Stacks + mSmmStackSize + EFI_PAGES_TO_SIZE(1) + (mSmmStackSize + mSmmShadowStackSize) * Index,\r
+ EFI_PAGES_TO_SIZE(1)\r
+ );\r
+ }\r
+ }\r
+ }\r
\r
//\r
// Fill in SMM Reserved Regions\r