CET Shadow Stack(SHSTK) and Indirect Branch Tracking(IBT) are enumerated via CPUID.(EAX=07H,ECX=0H):ECX[bit 7] and EDX[bit 20] respectively. Two CET bits (bit 11 and 12) are defined in MSR_IA32_XSS for XSAVE. They correspond to CET states in user and supervisor mode respectively.
Signed-off-by: Yang Weijiang <weijiang.y...@intel.com> --- target/i386/cpu.c | 18 ++++++++++++++++++ target/i386/cpu.h | 23 ++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 38eab02b3d..5496fd68d4 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1071,6 +1071,16 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { }, [FEAT_XSAVE_XSS_LO] = { .type = CPUID_FEATURE_WORD, + .feat_names = { + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, "cet-u", + "cet-s", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + }, .cpuid = { .eax = 0xD, .needs_ecx = true, @@ -1497,6 +1507,14 @@ static const ExtSaveArea x86_ext_save_areas[] = { { .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU, .offset = offsetof(X86XSaveArea, pkru_state), .size = sizeof(XSavePKRU) }, + [XSTATE_CET_U_BIT] = { + .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_CET_SHSTK, + .offset = 0, + .size = sizeof(XSavesCETU) }, + [XSTATE_CET_S_BIT] = { + .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_CET_SHSTK, + .offset = 0, + .size = sizeof(XSavesCETS) }, }; static uint32_t xsave_area_size(uint64_t mask) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 10bf4d8b51..d4563fa0e8 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -493,6 +493,8 @@ typedef enum X86Seg { #define XSTATE_ZMM_Hi256_BIT 6 #define XSTATE_Hi16_ZMM_BIT 7 #define XSTATE_PKRU_BIT 9 +#define XSTATE_CET_U_BIT 11 +#define XSTATE_CET_S_BIT 12 #define XSTATE_FP_MASK (1ULL << XSTATE_FP_BIT) #define XSTATE_SSE_MASK (1ULL << XSTATE_SSE_BIT) @@ -503,6 +505,8 @@ typedef enum X86Seg { #define XSTATE_ZMM_Hi256_MASK (1ULL << XSTATE_ZMM_Hi256_BIT) #define XSTATE_Hi16_ZMM_MASK (1ULL << XSTATE_Hi16_ZMM_BIT) #define XSTATE_PKRU_MASK (1ULL << XSTATE_PKRU_BIT) +#define XSTATE_CET_U_MASK (1ULL << XSTATE_CET_U_BIT) +#define XSTATE_CET_S_MASK (1ULL << XSTATE_CET_S_BIT) /* CPUID feature bits available in XCR0 */ #define CPUID_XSTATE_XCR0_MASK (XSTATE_FP_MASK | XSTATE_SSE_MASK | \ @@ -512,7 +516,7 @@ typedef enum X86Seg { XSTATE_Hi16_ZMM_MASK | XSTATE_PKRU_MASK) /* CPUID feature bits available in XSS */ -#define CPUID_XSTATE_XSS_MASK 0 +#define CPUID_XSTATE_XSS_MASK (XSTATE_CET_U_MASK) /* CPUID feature words */ typedef enum FeatureWord { @@ -760,6 +764,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_ECX_WAITPKG (1U << 5) /* Additional AVX-512 Vector Byte Manipulation Instruction */ #define CPUID_7_0_ECX_AVX512_VBMI2 (1U << 6) +/* CET SHSTK feature */ +#define CPUID_7_0_ECX_CET_SHSTK (1U << 7) /* Galois Field New Instructions */ #define CPUID_7_0_ECX_GFNI (1U << 8) /* Vector AES Instructions */ @@ -795,6 +801,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_EDX_SERIALIZE (1U << 14) /* TSX Suspend Load Address Tracking instruction */ #define CPUID_7_0_EDX_TSX_LDTRK (1U << 16) +/* CET IBT feature */ +#define CPUID_7_0_EDX_CET_IBT (1U << 20) /* Speculation Control */ #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Single Thread Indirect Branch Predictors */ @@ -1285,6 +1293,19 @@ typedef struct XSavePKRU { uint32_t padding; } XSavePKRU; +/* Ext. save area 11: User mode CET state */ +typedef struct XSavesCETU { + uint64_t u_cet; + uint64_t user_ssp; +} XSavesCETU; + +/* Ext. save area 12: Supervisor mode CET state */ +typedef struct XSavesCETS { + uint64_t kernel_ssp; + uint64_t pl1_ssp; + uint64_t pl2_ssp; +} XSavesCETS; + typedef struct X86XSaveArea { X86LegacyXSaveArea legacy; X86XSaveHeader header; -- 2.26.2