]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
UefiCpuPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmmFuncsArch.c
index 6844c3fc499d810bb041a38ae04084f934f090e7..6298571e29b2bc83cf05ffd8ad7fd18b1cd10ebc 100644 (file)
@@ -1,22 +1,52 @@
 /** @file\r
   SMM CPU misc functions for x64 arch specific.\r
-  \r
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
 \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "PiSmmCpuDxeSmm.h"\r
 \r
+EFI_PHYSICAL_ADDRESS                mGdtBuffer;\r
+UINTN                               mGdtBufferSize;\r
+\r
+extern BOOLEAN mCetSupported;\r
+extern UINTN mSmmShadowStackSize;\r
+\r
+X86_ASSEMBLY_PATCH_LABEL mPatchCetPl0Ssp;\r
+X86_ASSEMBLY_PATCH_LABEL mPatchCetInterruptSsp;\r
+X86_ASSEMBLY_PATCH_LABEL mPatchCetInterruptSspTable;\r
+UINT32 mCetPl0Ssp;\r
+UINT32 mCetInterruptSsp;\r
+UINT32 mCetInterruptSspTable;\r
+\r
+UINTN  mSmmInterruptSspTables;\r
+\r
+/**\r
+  Initialize IDT for SMM Stack Guard.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InitializeIDTSmmStackGuard (\r
+  VOID\r
+  )\r
+{\r
+  IA32_IDT_GATE_DESCRIPTOR  *IdtGate;\r
+\r
+  //\r
+  // If SMM Stack Guard feature is enabled, set the IST field of\r
+  // the interrupt gate for Page Fault Exception to be 1\r
+  //\r
+  IdtGate = (IA32_IDT_GATE_DESCRIPTOR *)gcSmiIdtr.Base;\r
+  IdtGate += EXCEPT_IA32_PAGE_FAULT;\r
+  IdtGate->Bits.Reserved_0 = 1;\r
+}\r
+\r
 /**\r
   Initialize Gdt for all processors.\r
-  \r
+\r
   @param[in]   Cr3          CR3 value.\r
   @param[out]  GdtStepSize  The step size for GDT table.\r
 \r
@@ -41,8 +71,10 @@ InitGdt (
   // on each SMI entry.\r
   //\r
   GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE + 7) & ~7; // 8 bytes aligned\r
-  GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
+  mGdtBufferSize = GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;\r
+  GdtTssTables = (UINT8*)AllocateCodePages (EFI_SIZE_TO_PAGES (mGdtBufferSize));\r
   ASSERT (GdtTssTables != NULL);\r
+  mGdtBuffer = (UINTN)GdtTssTables;\r
   GdtTableStepSize = GdtTssTableSize;\r
 \r
   for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {\r
@@ -84,7 +116,6 @@ GetProtectedModeCS (
   UINTN                    GdtEntryCount;\r
   UINT16                   Index;\r
 \r
-  Index = (UINT16) -1;\r
   AsmReadGdtr (&GdtrDesc);\r
   GdtEntryCount = (GdtrDesc.Limit + 1) / sizeof (IA32_SEGMENT_DESCRIPTOR);\r
   GdtEntry = (IA32_SEGMENT_DESCRIPTOR *) GdtrDesc.Base;\r
@@ -96,31 +127,31 @@ GetProtectedModeCS (
     }\r
     GdtEntry++;\r
   }\r
-  ASSERT (Index != -1);\r
+  ASSERT (Index != GdtEntryCount);\r
   return Index * 8;\r
 }\r
 \r
 /**\r
   Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.\r
 \r
-  @param[in] ApHltLoopCode    The 32-bit address of the safe hlt-loop function.\r
-  @param[in] TopOfStack       A pointer to the new stack to use for the ApHltLoopCode.\r
-  @param[in] NumberToFinish   Semaphore of APs finish count.\r
+  @param[in] ApHltLoopCode          The address of the safe hlt-loop function.\r
+  @param[in] TopOfStack             A pointer to the new stack to use for the ApHltLoopCode.\r
+  @param[in] NumberToFinishAddress  Address of Semaphore of APs finish count.\r
 \r
 **/\r
 VOID\r
 TransferApToSafeState (\r
-  IN UINT32             ApHltLoopCode,\r
-  IN UINT32             TopOfStack,\r
-  IN UINT32             *NumberToFinish\r
+  IN UINTN  ApHltLoopCode,\r
+  IN UINTN  TopOfStack,\r
+  IN UINTN  NumberToFinishAddress\r
   )\r
 {\r
   AsmDisablePaging64 (\r
     GetProtectedModeCS (),\r
-    (UINT32) (UINTN) ApHltLoopCode,\r
-    (UINT32) (UINTN) NumberToFinish,\r
+    (UINT32)ApHltLoopCode,\r
+    (UINT32)NumberToFinishAddress,\r
     0,\r
-    TopOfStack\r
+    (UINT32)TopOfStack\r
     );\r
   //\r
   // It should never reach here\r
@@ -128,4 +159,47 @@ TransferApToSafeState (
   ASSERT (FALSE);\r
 }\r
 \r
+/**\r
+  Initialize the shadow stack related data structure.\r
+\r
+  @param CpuIndex     The index of CPU.\r
+  @param ShadowStack  The bottom of the shadow stack for this CPU.\r
+**/\r
+VOID\r
+InitShadowStack (\r
+  IN UINTN  CpuIndex,\r
+  IN VOID   *ShadowStack\r
+  )\r
+{\r
+  UINTN       SmmShadowStackSize;\r
+  UINT64      *InterruptSspTable;\r
+\r
+  if ((PcdGet32 (PcdControlFlowEnforcementPropertyMask) != 0) && mCetSupported) {\r
+    SmmShadowStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmShadowStackSize)));\r
+    if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
+      SmmShadowStackSize += EFI_PAGES_TO_SIZE (2);\r
+    }\r
+    mCetPl0Ssp = (UINT32)((UINTN)ShadowStack + SmmShadowStackSize - sizeof(UINT64));\r
+    PatchInstructionX86 (mPatchCetPl0Ssp, mCetPl0Ssp, 4);\r
+    DEBUG ((DEBUG_INFO, "mCetPl0Ssp - 0x%x\n", mCetPl0Ssp));\r
+    DEBUG ((DEBUG_INFO, "ShadowStack - 0x%x\n", ShadowStack));\r
+    DEBUG ((DEBUG_INFO, "  SmmShadowStackSize - 0x%x\n", SmmShadowStackSize));\r
+\r
+    if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
+      if (mSmmInterruptSspTables == 0) {\r
+        mSmmInterruptSspTables = (UINTN)AllocateZeroPool(sizeof(UINT64) * 8 * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus);\r
+        ASSERT (mSmmInterruptSspTables != 0);\r
+        DEBUG ((DEBUG_INFO, "mSmmInterruptSspTables - 0x%x\n", mSmmInterruptSspTables));\r
+      }\r
+      mCetInterruptSsp = (UINT32)((UINTN)ShadowStack + EFI_PAGES_TO_SIZE(1) - sizeof(UINT64));\r
+      mCetInterruptSspTable = (UINT32)(UINTN)(mSmmInterruptSspTables + sizeof(UINT64) * 8 * CpuIndex);\r
+      InterruptSspTable = (UINT64 *)(UINTN)mCetInterruptSspTable;\r
+      InterruptSspTable[1] = mCetInterruptSsp;\r
+      PatchInstructionX86 (mPatchCetInterruptSsp, mCetInterruptSsp, 4);\r
+      PatchInstructionX86 (mPatchCetInterruptSspTable, mCetInterruptSspTable, 4);\r
+      DEBUG ((DEBUG_INFO, "mCetInterruptSsp - 0x%x\n", mCetInterruptSsp));\r
+      DEBUG ((DEBUG_INFO, "mCetInterruptSspTable - 0x%x\n", mCetInterruptSspTable));\r
+    }\r
+  }\r
+}\r
 \r