mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-08-26 22:23:12 -04:00
i386/kvm: Add save/restore support for CET MSRs
CET (architectural) MSRs include:
MSR_IA32_U_CET - user mode CET control bits.
MSR_IA32_S_CET - supervisor mode CET control bits.
MSR_IA32_PL{0,1,2,3}_SSP - linear addresses of SSPs for user/kernel modes.
MSR_IA32_INT_SSP_TAB - linear address of interrupt SSP table
Since FRED also needs to save/restore MSR_IA32_PL0_SSP, to avoid duplicate
operations, make FRED only save/restore MSR_IA32_PL0_SSP when CET-SHSTK
is not enumerated.
And considerring MSR_IA32_SSP_TBL_ADDR is only presented on 64 bit
processor, wrap it with TARGET_X86_64 macro.
For other MSRs, add save/restore support directly.
Tested-by: Farrah Chen <farrah.chen@intel.com>
Suggested-by: Xin Li (Intel) <xin@zytor.com>
Signed-off-by: Yang Weijiang <weijiang.yang@intel.com>
Co-developed-by: Chao Gao <chao.gao@intel.com>
Signed-off-by: Chao Gao <chao.gao@intel.com>
Co-developed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Link: https://lore.kernel.org/r/20251211060801.3600039-15-zhao1.liu@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
0fa1025904
commit
b6f85c5e45
2 changed files with 98 additions and 19 deletions
|
|
@ -543,7 +543,7 @@ typedef enum X86Seg {
|
|||
#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 */
|
||||
|
|
@ -554,9 +554,6 @@ typedef enum X86Seg {
|
|||
#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
|
||||
|
|
@ -583,6 +580,15 @@ typedef enum X86Seg {
|
|||
#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
|
||||
|
|
@ -1973,8 +1979,16 @@ typedef struct CPUArchState {
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -4009,11 +4009,14 @@ static int kvm_put_msrs(X86CPU *cpu, KvmPutState level)
|
|||
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
|
||||
|
|
@ -4267,6 +4270,26 @@ static int kvm_put_msrs(X86CPU *cpu, KvmPutState level)
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -4501,11 +4524,14 @@ static int kvm_get_msrs(X86CPU *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
|
||||
|
|
@ -4663,6 +4689,25 @@ static int kvm_get_msrs(X86CPU *cpu)
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -4757,9 +4802,6 @@ static int kvm_get_msrs(X86CPU *cpu)
|
|||
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;
|
||||
|
|
@ -5013,6 +5055,29 @@ static int kvm_get_msrs(X86CPU *cpu)
|
|||
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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue