/** @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
#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
// 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
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
/**\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
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