#define MSR_IA32_XFD 0x000001c4
#define MSR_IA32_XFD_ERR 0x000001c5
-/* FRED MSRs */
+/* FRED MSRs (MSR_IA32_FRED_SSP0 is defined as MSR_IA32_PL0_SSP in CET MSRs) */
#define MSR_IA32_FRED_RSP0 0x000001cc /* Stack level 0 regular stack pointer */
#define MSR_IA32_FRED_RSP1 0x000001cd /* Stack level 1 regular stack pointer */
#define MSR_IA32_FRED_RSP2 0x000001ce /* Stack level 2 regular stack pointer */
#define MSR_IA32_FRED_SSP3 0x000001d3 /* Stack level 3 shadow stack pointer in ring 0 */
#define MSR_IA32_FRED_CONFIG 0x000001d4 /* FRED Entrypoint and interrupt stack level */
-/* FRED and CET MSR */
-#define MSR_IA32_PL0_SSP 0x000006a4 /* ring-0 shadow stack pointer (aka MSR_IA32_FRED_SSP0 for FRED) */
-
#define MSR_IA32_BNDCFGS 0x00000d90
#define MSR_IA32_XSS 0x00000da0
#define MSR_IA32_UMWAIT_CONTROL 0xe1
#define MSR_APIC_START 0x00000800
#define MSR_APIC_END 0x000008ff
+/* CET MSRs */
+#define MSR_IA32_U_CET 0x000006a0 /* user mode cet */
+#define MSR_IA32_S_CET 0x000006a2 /* kernel mode cet */
+#define MSR_IA32_PL0_SSP 0x000006a4 /* ring-0 shadow stack pointer */
+#define MSR_IA32_PL1_SSP 0x000006a5 /* ring-1 shadow stack pointer */
+#define MSR_IA32_PL2_SSP 0x000006a6 /* ring-2 shadow stack pointer */
+#define MSR_IA32_PL3_SSP 0x000006a7 /* ring-3 shadow stack pointer */
+#define MSR_IA32_INT_SSP_TAB 0x000006a8 /* exception shadow stack table */
+
#define XSTATE_FP_BIT 0
#define XSTATE_SSE_BIT 1
#define XSTATE_YMM_BIT 2
uint64_t fred_config;
#endif
- /* MSR used for both FRED and CET (SHSTK) */
- uint64_t pl0_ssp;
+ /* CET MSRs */
+ uint64_t u_cet;
+ uint64_t s_cet;
+ uint64_t pl0_ssp; /* also used for FRED */
+ uint64_t pl1_ssp;
+ uint64_t pl2_ssp;
+ uint64_t pl3_ssp;
+#ifdef TARGET_X86_64
+ uint64_t int_ssp_table;
+#endif
uint64_t tsc_adjust;
uint64_t tsc_deadline;
kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP2, env->fred_ssp2);
kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP3, env->fred_ssp3);
kvm_msr_entry_add(cpu, MSR_IA32_FRED_CONFIG, env->fred_config);
- /*
- * Aka MSR_IA32_FRED_SSP0. This MSR is accessible even if
- * CET shadow stack is not supported.
- */
- kvm_msr_entry_add(cpu, MSR_IA32_PL0_SSP, env->pl0_ssp);
+
+ if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_CET_SHSTK)) {
+ /*
+ * Aka MSR_IA32_FRED_SSP0. This MSR is accessible even if
+ * CET shadow stack is not supported.
+ */
+ kvm_msr_entry_add(cpu, MSR_IA32_PL0_SSP, env->pl0_ssp);
+ }
}
}
#endif
}
}
+ 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) {
+ kvm_msr_entry_add(cpu, MSR_IA32_U_CET, env->u_cet);
+ kvm_msr_entry_add(cpu, MSR_IA32_S_CET, env->s_cet);
+
+ if (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_CET_SHSTK) {
+ kvm_msr_entry_add(cpu, MSR_IA32_PL0_SSP, env->pl0_ssp);
+ kvm_msr_entry_add(cpu, MSR_IA32_PL1_SSP, env->pl1_ssp);
+ kvm_msr_entry_add(cpu, MSR_IA32_PL2_SSP, env->pl2_ssp);
+ kvm_msr_entry_add(cpu, MSR_IA32_PL3_SSP, env->pl3_ssp);
+
+#ifdef TARGET_X86_64
+ if (lm_capable_kernel) {
+ kvm_msr_entry_add(cpu, MSR_IA32_INT_SSP_TAB,
+ env->int_ssp_table);
+ }
+#endif
+ }
+ }
+
return kvm_buf_set_msrs(cpu);
}
kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP2, 0);
kvm_msr_entry_add(cpu, MSR_IA32_FRED_SSP3, 0);
kvm_msr_entry_add(cpu, MSR_IA32_FRED_CONFIG, 0);
- /*
- * Aka MSR_IA32_FRED_SSP0. This MSR is accessible even if
- * CET shadow stack is not supported.
- */
- kvm_msr_entry_add(cpu, MSR_IA32_PL0_SSP, 0);
+
+ if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_CET_SHSTK)) {
+ /*
+ * Aka MSR_IA32_FRED_SSP0. This MSR is accessible even if
+ * CET shadow stack is not supported.
+ */
+ kvm_msr_entry_add(cpu, MSR_IA32_PL0_SSP, 0);
+ }
}
}
#endif
}
}
+ 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) {
+ kvm_msr_entry_add(cpu, MSR_IA32_U_CET, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_S_CET, 0);
+
+ if (env->features[FEAT_7_0_EDX] & CPUID_7_0_ECX_CET_SHSTK) {
+ kvm_msr_entry_add(cpu, MSR_IA32_PL0_SSP, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_PL1_SSP, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_PL2_SSP, 0);
+ kvm_msr_entry_add(cpu, MSR_IA32_PL3_SSP, 0);
+
+#ifdef TARGET_X86_64
+ if (lm_capable_kernel) {
+ kvm_msr_entry_add(cpu, MSR_IA32_INT_SSP_TAB, 0);
+ }
+#endif
+ }
+ }
+
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, cpu->kvm_msr_buf);
if (ret < 0) {
return ret;
case MSR_IA32_FRED_CONFIG:
env->fred_config = msrs[i].data;
break;
- case MSR_IA32_PL0_SSP: /* aka MSR_IA32_FRED_SSP0 */
- env->pl0_ssp = msrs[i].data;
- break;
#endif
case MSR_IA32_TSC:
env->tsc = msrs[i].data;
case MSR_ARCH_LBR_INFO_0 ... MSR_ARCH_LBR_INFO_0 + 31:
env->lbr_records[index - MSR_ARCH_LBR_INFO_0].info = msrs[i].data;
break;
+ case MSR_IA32_U_CET:
+ env->u_cet = msrs[i].data;
+ break;
+ case MSR_IA32_S_CET:
+ env->s_cet = msrs[i].data;
+ break;
+ case MSR_IA32_PL0_SSP: /* aka MSR_IA32_FRED_SSP0 */
+ env->pl0_ssp = msrs[i].data;
+ break;
+ case MSR_IA32_PL1_SSP:
+ env->pl1_ssp = msrs[i].data;
+ break;
+ case MSR_IA32_PL2_SSP:
+ env->pl2_ssp = msrs[i].data;
+ break;
+ case MSR_IA32_PL3_SSP:
+ env->pl3_ssp = msrs[i].data;
+ break;
+#ifdef TARGET_X86_64
+ case MSR_IA32_INT_SSP_TAB:
+ env->int_ssp_table = msrs[i].data;
+ break;
+#endif
case MSR_K7_HWCR:
env->msr_hwcr = msrs[i].data;
break;