]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
UefiCpuPkg/PiSmmCpu: Add Shadow Stack Support for X86 SMM.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / PiSmmCpuDxeSmm.h
index 61d4bd3085c86c4c769e69eb2c8fdd80d82b1147..84efb229819b727628c8b583c7180cc828d798f4 100644 (file)
@@ -1,7 +1,7 @@
 /** @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
@@ -64,6 +64,51 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "CpuService.h"\r
 #include "SmmProfile.h"\r
 \r
+//\r
+// CET definition\r
+//\r
+#define CPUID_CET_SS   BIT7\r
+#define CPUID_CET_IBT  BIT20\r
+\r
+#define CR4_CET_ENABLE  BIT23\r
+\r
+#define MSR_IA32_S_CET                     0x6A2\r
+#define MSR_IA32_PL0_SSP                   0x6A4\r
+#define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR  0x6A8\r
+\r
+typedef union {\r
+  struct {\r
+    // enable shadow stacks\r
+    UINT32  SH_STK_ENP:1;\r
+    // enable the WRSS{D,Q}W instructions.\r
+    UINT32  WR_SHSTK_EN:1;\r
+    // enable tracking of indirect call/jmp targets to be ENDBRANCH instruction.\r
+    UINT32  ENDBR_EN:1;\r
+    // enable legacy compatibility treatment for indirect call/jmp tracking.\r
+    UINT32  LEG_IW_EN:1;\r
+    // enable use of no-track prefix on indirect call/jmp.\r
+    UINT32  NO_TRACK_EN:1;\r
+    // disable suppression of CET indirect branch tracking on legacy compatibility.\r
+    UINT32  SUPPRESS_DIS:1;\r
+    UINT32  RSVD:4;\r
+    // indirect branch tracking is suppressed.\r
+    // This bit can be written to 1 only if TRACKER is written as IDLE.\r
+    UINT32  SUPPRESS:1;\r
+    // Value of the endbranch state machine\r
+    // Values: IDLE (0), WAIT_FOR_ENDBRANCH(1).\r
+    UINT32  TRACKER:1;\r
+    // linear address of a bitmap in memory indicating valid\r
+    // pages as target of CALL/JMP_indirect that do not land on ENDBRANCH when CET is enabled\r
+    // and not suppressed. Valid when ENDBR_EN is 1. Must be machine canonical when written on\r
+    // parts that support 64 bit mode. On parts that do not support 64 bit mode, the bits 63:32 are\r
+    // reserved and must be 0. This value is extended by 12 bits at the low end to form the base address\r
+    // (this automatically aligns the address on a 4-Kbyte boundary).\r
+    UINT32  EB_LEG_BITMAP_BASE_low:12;\r
+    UINT32  EB_LEG_BITMAP_BASE_high:32;\r
+  } Bits;\r
+  UINT64   Uint64;\r
+} MSR_IA32_CET;\r
+\r
 //\r
 // MSRs required for configuration of SMM Code Access Check\r
 //\r
@@ -127,9 +172,11 @@ typedef struct {
 // Size of Task-State Segment defined in IA32 Manual\r
 //\r
 #define TSS_SIZE              104\r
+#define EXCEPTION_TSS_SIZE    (TSS_SIZE + 4) // Add 4 bytes SSP\r
 #define TSS_X64_IST1_OFFSET   36\r
 #define TSS_IA32_CR3_OFFSET   28\r
 #define TSS_IA32_ESP_OFFSET   56\r
+#define TSS_IA32_SSP_OFFSET   104\r
 \r
 #define CR0_WP                BIT16\r
 \r
@@ -305,6 +352,8 @@ X86_ASSEMBLY_PATCH_LABEL            gPatchSmmCr3;
 extern UINT32                       mSmmCr4;\r
 X86_ASSEMBLY_PATCH_LABEL            gPatchSmmCr4;\r
 X86_ASSEMBLY_PATCH_LABEL            gPatchSmmInitStack;\r
+X86_ASSEMBLY_PATCH_LABEL            mPatchCetSupported;\r
+extern BOOLEAN                      mCetSupported;\r
 \r
 /**\r
   Semaphore operation for all processor relocate SMMBase.\r
@@ -418,14 +467,16 @@ Gen4GPageTable (
 /**\r
   Initialize global data for MP synchronization.\r
 \r
-  @param Stacks       Base address of SMI stack buffer for all processors.\r
-  @param StackSize    Stack size for each processor in SMM.\r
+  @param Stacks             Base address of SMI stack buffer for all processors.\r
+  @param StackSize          Stack size for each processor in SMM.\r
+  @param ShadowStackSize    Shadow Stack size for each processor in SMM.\r
 \r
 **/\r
 UINT32\r
 InitializeMpServiceData (\r
   IN VOID        *Stacks,\r
-  IN UINTN       StackSize\r
+  IN UINTN       StackSize,\r
+  IN UINTN       ShadowStackSize\r
   );\r
 \r
 /**\r
@@ -1036,6 +1087,50 @@ TransferApToSafeState (
   IN UINTN  NumberToFinishAddress\r
   );\r
 \r
+/**\r
+  Set ShadowStack memory.\r
+\r
+  @param[in]  Cr3              The page table base address.\r
+  @param[in]  BaseAddress      The physical address that is the start address of a memory region.\r
+  @param[in]  Length           The size in bytes of the memory region.\r
+\r
+  @retval EFI_SUCCESS           The shadow stack memory is set.\r
+**/\r
+EFI_STATUS\r
+SetShadowStack (\r
+  IN  UINTN                                      Cr3,\r
+  IN  EFI_PHYSICAL_ADDRESS                       BaseAddress,\r
+  IN  UINT64                                     Length\r
+  );\r
+\r
+/**\r
+  Set not present memory.\r
+\r
+  @param[in]  Cr3              The page table base address.\r
+  @param[in]  BaseAddress      The physical address that is the start address of a memory region.\r
+  @param[in]  Length           The size in bytes of the memory region.\r
+\r
+  @retval EFI_SUCCESS           The not present memory is set.\r
+**/\r
+EFI_STATUS\r
+SetNotPresentPage (\r
+  IN  UINTN                                      Cr3,\r
+  IN  EFI_PHYSICAL_ADDRESS                       BaseAddress,\r
+  IN  UINT64                                     Length\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
 /**\r
   This function set given attributes of the memory region specified by\r
   BaseAddress and Length.\r