- 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
+ mSmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize)));\r
+\r
+ if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
+ //\r
+ // SMM Stack Guard Enabled\r
+ // Append Shadow Stack after normal stack\r
+ // 2 more pages is allocated for each processor, one is guard page and the other is known good shadow stack.\r
+ //\r
+ // |= Stacks\r
+ // +--------------------------------------------------+---------------------------------------------------------------+\r
+ // | Known Good Stack | Guard Page | SMM Stack | Known Good Shadow Stack | Guard Page | SMM Shadow Stack |\r
+ // +--------------------------------------------------+---------------------------------------------------------------+\r
+ // | 4K | 4K |PcdCpuSmmStackSize| 4K | 4K |PcdCpuSmmShadowStackSize|\r
+ // |<---------------- mSmmStackSize ----------------->|<--------------------- mSmmShadowStackSize ------------------->|\r
+ // | |\r
+ // |<-------------------------------------------- Processor N ------------------------------------------------------->|\r
+ //\r
+ mSmmShadowStackSize += EFI_PAGES_TO_SIZE (2);\r
+ } else {\r
+ //\r
+ // SMM Stack Guard Disabled (Known Good Stack is still required for potential stack switch.)\r
+ // Append Shadow Stack after normal stack with 1 more page as known good shadow stack.\r
+ // 1 more pages is allocated for each processor, it is known good stack.\r
+ //\r
+ //\r
+ // |= Stacks\r
+ // +-------------------------------------+--------------------------------------------------+\r
+ // | Known Good Stack | SMM Stack | Known Good Shadow Stack | SMM Shadow Stack |\r
+ // +-------------------------------------+--------------------------------------------------+\r
+ // | 4K |PcdCpuSmmStackSize| 4K |PcdCpuSmmShadowStackSize|\r
+ // |<---------- mSmmStackSize ---------->|<--------------- mSmmShadowStackSize ------------>|\r
+ // | |\r
+ // |<-------------------------------- Processor N ----------------------------------------->|\r
+ //\r
+ mSmmShadowStackSize += EFI_PAGES_TO_SIZE (1);\r
+ mSmmStackSize += EFI_PAGES_TO_SIZE (1);\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