#define CR4_SMEP_MASK (1U << 20)
#define CR4_SMAP_MASK (1U << 21)
#define CR4_PKE_MASK (1U << 22)
+#define CR4_CET_MASK (1U << 23)
#define CR4_PKS_MASK (1U << 24)
#define CR4_LAM_SUP_MASK (1U << 28)
| CR4_OSFXSR_MASK | CR4_OSXMMEXCPT_MASK | CR4_UMIP_MASK \
| CR4_LA57_MASK \
| CR4_FSGSBASE_MASK | CR4_PCIDE_MASK | CR4_OSXSAVE_MASK \
- | CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK \
- | CR4_LAM_SUP_MASK | CR4_FRED_MASK))
+ | CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_CET_MASK \
+ | CR4_PKS_MASK | CR4_LAM_SUP_MASK | CR4_FRED_MASK))
#define DR6_BD (1 << 13)
#define DR6_BS (1 << 14)
if (!(env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED)) {
reserved_bits |= CR4_FRED_MASK;
}
+ if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_CET_SHSTK) &&
+ !(env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_CET_IBT)) {
+ reserved_bits |= CR4_CET_MASK;
+ }
return reserved_bits;
}
new_cr4 &= ~CR4_LAM_SUP_MASK;
}
+ /*
+ * In fact, "CR4.CET can be set only if CR0.WP is set, and it must be
+ * clear before CR0.WP can be cleared". However, here we only check
+ * CR4.CET based on the supported CPUID CET bit, without checking the
+ * dependency on CR4.WP - the latter need to be determined by the
+ * underlying accelerators.
+ */
+ if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_CET_SHSTK) &&
+ !(env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_CET_IBT)) {
+ new_cr4 &= ~CR4_CET_MASK;
+ }
+
env->cr[4] = new_cr4;
env->hflags = hflags;