]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
UefiCpuPkg\CpuSmm: Save & restore CR2 on-demand paging in SMM
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / PiSmmCpuDxeSmm.h
index f91ddd35d2047bf651cc637fe83fc662597612e7..38f91041179c8e64e8bf00f15ca599d17de1782c 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
@@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/SmmMemoryAttribute.h>\r
 \r
 #include <Guid/AcpiS3Context.h>\r
+#include <Guid/MemoryAttributesTable.h>\r
 #include <Guid/PiSmmMemoryAttributesTable.h>\r
 \r
 #include <Library/BaseLib.h>\r
@@ -37,7 +38,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/DebugLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/PcdLib.h>\r
-#include <Library/CacheMaintenanceLib.h>\r
 #include <Library/MtrrLib.h>\r
 #include <Library/SmmCpuPlatformHookLib.h>\r
 #include <Library/SmmServicesTableLib.h>\r
@@ -45,6 +45,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/UefiRuntimeServicesTableLib.h>\r
 #include <Library/DebugAgentLib.h>\r
+#include <Library/UefiLib.h>\r
 #include <Library/HobLib.h>\r
 #include <Library/LocalApicLib.h>\r
 #include <Library/UefiCpuLib.h>\r
@@ -52,6 +53,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/ReportStatusCodeLib.h>\r
 #include <Library/SmmCpuFeaturesLib.h>\r
 #include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/RegisterCpuFeaturesLib.h>\r
 \r
 #include <AcpiCpuData.h>\r
 #include <CpuHotPlugData.h>\r
@@ -62,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
@@ -125,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
@@ -295,23 +344,16 @@ WriteSaveStateRegister (
   IN CONST VOID                   *Buffer\r
   );\r
 \r
-//\r
-//\r
-//\r
-typedef struct {\r
-  UINT32                            Offset;\r
-  UINT16                            Segment;\r
-  UINT16                            Reserved;\r
-} IA32_FAR_ADDRESS;\r
-\r
-extern IA32_FAR_ADDRESS             gSmmJmpAddr;\r
-\r
 extern CONST UINT8                  gcSmmInitTemplate[];\r
 extern CONST UINT16                 gcSmmInitSize;\r
-extern UINT32                       gSmmCr0;\r
-extern UINT32                       gSmmCr3;\r
-extern UINT32                       gSmmCr4;\r
-extern UINTN                        gSmmInitStack;\r
+X86_ASSEMBLY_PATCH_LABEL            gPatchSmmCr0;\r
+extern UINT32                       mSmmCr0;\r
+X86_ASSEMBLY_PATCH_LABEL            gPatchSmmCr3;\r
+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
@@ -354,13 +396,6 @@ typedef struct {
   volatile BOOLEAN              *CandidateBsp;\r
 } SMM_DISPATCHER_MP_SYNC_DATA;\r
 \r
-#define MSR_SPIN_LOCK_INIT_NUM 15\r
-\r
-typedef struct {\r
-  SPIN_LOCK    *SpinLock;\r
-  UINT32       MsrIndex;\r
-} MP_MSR_LOCK;\r
-\r
 #define SMM_PSD_OFFSET              0xfb00\r
 \r
 ///\r
@@ -372,7 +407,6 @@ typedef struct {
   volatile BOOLEAN     *AllCpusInSync;\r
   SPIN_LOCK            *PFLock;\r
   SPIN_LOCK            *CodeAccessCheckLock;\r
-  SPIN_LOCK            *MemoryMappedLock;\r
 } SMM_CPU_SEMAPHORE_GLOBAL;\r
 \r
 ///\r
@@ -384,21 +418,12 @@ typedef struct {
   volatile BOOLEAN                  *Present;\r
 } SMM_CPU_SEMAPHORE_CPU;\r
 \r
-///\r
-/// All MSRs semaphores' pointer and counter\r
-///\r
-typedef struct {\r
-  SPIN_LOCK            *Msr;\r
-  UINTN                AvailableCounter;\r
-} SMM_CPU_SEMAPHORE_MSR;\r
-\r
 ///\r
 /// All semaphores' information\r
 ///\r
 typedef struct {\r
   SMM_CPU_SEMAPHORE_GLOBAL          SemaphoreGlobal;\r
   SMM_CPU_SEMAPHORE_CPU             SemaphoreCpu;\r
-  SMM_CPU_SEMAPHORE_MSR             SemaphoreMsr;\r
 } SMM_CPU_SEMAPHORES;\r
 \r
 extern IA32_DESCRIPTOR                     gcSmiGdtr;\r
@@ -417,7 +442,6 @@ extern SMM_CPU_SEMAPHORES                  mSmmCpuSemaphores;
 extern UINTN                               mSemaphoreSize;\r
 extern SPIN_LOCK                           *mPFLock;\r
 extern SPIN_LOCK                           *mConfigSmmCodeAccessCheckLock;\r
-extern SPIN_LOCK                           *mMemoryMappedLock;\r
 extern EFI_SMRAM_DESCRIPTOR                *mSmmCpuSmramRanges;\r
 extern UINTN                               mSmmCpuSmramRangeCount;\r
 extern UINT8                               mPhysicalAddressBits;\r
@@ -443,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
@@ -1061,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
@@ -1173,4 +1243,26 @@ EFIAPI
 PiSmmCpuSmiEntryFixupAddress (\r
  );\r
 \r
+/**\r
+  This function reads CR2 register when on-demand paging is enabled\r
+  for 64 bit and no action for 32 bit.\r
+\r
+  @param[out]  *Cr2  Pointer to variable to hold CR2 register value.\r
+**/\r
+VOID\r
+SaveCr2 (\r
+  OUT UINTN  *Cr2\r
+  );\r
+\r
+/**\r
+  This function writes into CR2 register when on-demand paging is enabled\r
+  for 64 bit and no action for 32 bit.\r
+\r
+  @param[in]  Cr2  Value to write into CR2 register.\r
+**/\r
+VOID\r
+RestoreCr2 (\r
+  IN UINTN  Cr2\r
+  );\r
+\r
 #endif\r