Message ID | 20201106011637.14289-12-weijiang.yang@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Introduce support for guest CET feature | expand |
On 06/11/20 02:16, Yang Weijiang wrote: > Pass through all CET MSRs when the associated CET component (kernel vs. > user) is enabled to improve guest performance. All CET MSRs are context > switched, either via dedicated VMCS fields or XSAVES. > > Co-developed-by: Zhang Yi Z <yi.z.zhang@linux.intel.com> > Signed-off-by: Zhang Yi Z <yi.z.zhang@linux.intel.com> > Co-developed-by: Sean Christopherson <sean.j.christopherson@intel.com> > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> > Signed-off-by: Yang Weijiang <weijiang.yang@intel.com> > --- > arch/x86/kvm/vmx/vmx.c | 29 +++++++++++++++++++++++++++++ > 1 file changed, 29 insertions(+) > > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c > index c88a6e1721b1..6ba2027a3d44 100644 > --- a/arch/x86/kvm/vmx/vmx.c > +++ b/arch/x86/kvm/vmx/vmx.c > @@ -7366,6 +7366,32 @@ static void update_intel_pt_cfg(struct kvm_vcpu *vcpu) > vmx->pt_desc.ctl_bitmask &= ~(0xfULL << (32 + i * 4)); > } > > +static bool is_cet_state_supported(struct kvm_vcpu *vcpu, u32 xss_state) > +{ > + return (vcpu->arch.guest_supported_xss & xss_state) && > + (guest_cpuid_has(vcpu, X86_FEATURE_SHSTK) || > + guest_cpuid_has(vcpu, X86_FEATURE_IBT)); > +} > + > +static void vmx_update_intercept_for_cet_msr(struct kvm_vcpu *vcpu) > +{ > + bool incpt = !is_cet_state_supported(vcpu, XFEATURE_MASK_CET_USER); > + > + vmx_set_intercept_for_msr(vcpu, MSR_IA32_U_CET, MSR_TYPE_RW, incpt); > + > + incpt |= !guest_cpuid_has(vcpu, X86_FEATURE_SHSTK); > + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL3_SSP, MSR_TYPE_RW, incpt); > + > + incpt = !is_cet_state_supported(vcpu, XFEATURE_MASK_CET_KERNEL); > + vmx_set_intercept_for_msr(vcpu, MSR_IA32_S_CET, MSR_TYPE_RW, incpt); > + > + incpt |= !guest_cpuid_has(vcpu, X86_FEATURE_SHSTK); > + vmx_set_intercept_for_msr(vcpu, MSR_IA32_INT_SSP_TAB, MSR_TYPE_RW, incpt); > + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL0_SSP, MSR_TYPE_RW, incpt); > + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL1_SSP, MSR_TYPE_RW, incpt); > + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL2_SSP, MSR_TYPE_RW, incpt); > +} > + > static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) > { > struct vcpu_vmx *vmx = to_vmx(vcpu); > @@ -7409,6 +7435,9 @@ static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) > > /* Refresh #PF interception to account for MAXPHYADDR changes. */ > update_exception_bitmap(vcpu); > + > + if (kvm_cet_supported()) > + vmx_update_intercept_for_cet_msr(vcpu); > } > > static __init void vmx_set_cpu_caps(void) > Can you do this only if CR4.CET=1? Paolo
On 28/01/21 18:54, Paolo Bonzini wrote: > On 06/11/20 02:16, Yang Weijiang wrote: >> Pass through all CET MSRs when the associated CET component (kernel vs. >> user) is enabled to improve guest performance. All CET MSRs are context >> switched, either via dedicated VMCS fields or XSAVES. >> >> Co-developed-by: Zhang Yi Z <yi.z.zhang@linux.intel.com> >> Signed-off-by: Zhang Yi Z <yi.z.zhang@linux.intel.com> >> Co-developed-by: Sean Christopherson <sean.j.christopherson@intel.com> >> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> >> Signed-off-by: Yang Weijiang <weijiang.yang@intel.com> >> --- >> arch/x86/kvm/vmx/vmx.c | 29 +++++++++++++++++++++++++++++ >> 1 file changed, 29 insertions(+) >> >> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c >> index c88a6e1721b1..6ba2027a3d44 100644 >> --- a/arch/x86/kvm/vmx/vmx.c >> +++ b/arch/x86/kvm/vmx/vmx.c >> @@ -7366,6 +7366,32 @@ static void update_intel_pt_cfg(struct kvm_vcpu >> *vcpu) >> vmx->pt_desc.ctl_bitmask &= ~(0xfULL << (32 + i * 4)); >> } >> +static bool is_cet_state_supported(struct kvm_vcpu *vcpu, u32 xss_state) >> +{ >> + return (vcpu->arch.guest_supported_xss & xss_state) && >> + (guest_cpuid_has(vcpu, X86_FEATURE_SHSTK) || >> + guest_cpuid_has(vcpu, X86_FEATURE_IBT)); >> +} >> + >> +static void vmx_update_intercept_for_cet_msr(struct kvm_vcpu *vcpu) >> +{ >> + bool incpt = !is_cet_state_supported(vcpu, XFEATURE_MASK_CET_USER); >> + >> + vmx_set_intercept_for_msr(vcpu, MSR_IA32_U_CET, MSR_TYPE_RW, incpt); >> + >> + incpt |= !guest_cpuid_has(vcpu, X86_FEATURE_SHSTK); >> + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL3_SSP, MSR_TYPE_RW, >> incpt); >> + >> + incpt = !is_cet_state_supported(vcpu, XFEATURE_MASK_CET_KERNEL); >> + vmx_set_intercept_for_msr(vcpu, MSR_IA32_S_CET, MSR_TYPE_RW, incpt); >> + >> + incpt |= !guest_cpuid_has(vcpu, X86_FEATURE_SHSTK); >> + vmx_set_intercept_for_msr(vcpu, MSR_IA32_INT_SSP_TAB, >> MSR_TYPE_RW, incpt); >> + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL0_SSP, MSR_TYPE_RW, >> incpt); >> + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL1_SSP, MSR_TYPE_RW, >> incpt); >> + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL2_SSP, MSR_TYPE_RW, >> incpt); >> +} >> + >> static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) >> { >> struct vcpu_vmx *vmx = to_vmx(vcpu); >> @@ -7409,6 +7435,9 @@ static void vmx_vcpu_after_set_cpuid(struct >> kvm_vcpu *vcpu) >> /* Refresh #PF interception to account for MAXPHYADDR changes. */ >> update_exception_bitmap(vcpu); >> + >> + if (kvm_cet_supported()) >> + vmx_update_intercept_for_cet_msr(vcpu); >> } >> static __init void vmx_set_cpu_caps(void) >> > > Can you do this only if CR4.CET=1? Actually, considering this is XSAVES and not RDMSR/WRMSR state, this is okay as is. Paolo
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index c88a6e1721b1..6ba2027a3d44 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7366,6 +7366,32 @@ static void update_intel_pt_cfg(struct kvm_vcpu *vcpu) vmx->pt_desc.ctl_bitmask &= ~(0xfULL << (32 + i * 4)); } +static bool is_cet_state_supported(struct kvm_vcpu *vcpu, u32 xss_state) +{ + return (vcpu->arch.guest_supported_xss & xss_state) && + (guest_cpuid_has(vcpu, X86_FEATURE_SHSTK) || + guest_cpuid_has(vcpu, X86_FEATURE_IBT)); +} + +static void vmx_update_intercept_for_cet_msr(struct kvm_vcpu *vcpu) +{ + bool incpt = !is_cet_state_supported(vcpu, XFEATURE_MASK_CET_USER); + + vmx_set_intercept_for_msr(vcpu, MSR_IA32_U_CET, MSR_TYPE_RW, incpt); + + incpt |= !guest_cpuid_has(vcpu, X86_FEATURE_SHSTK); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL3_SSP, MSR_TYPE_RW, incpt); + + incpt = !is_cet_state_supported(vcpu, XFEATURE_MASK_CET_KERNEL); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_S_CET, MSR_TYPE_RW, incpt); + + incpt |= !guest_cpuid_has(vcpu, X86_FEATURE_SHSTK); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_INT_SSP_TAB, MSR_TYPE_RW, incpt); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL0_SSP, MSR_TYPE_RW, incpt); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL1_SSP, MSR_TYPE_RW, incpt); + vmx_set_intercept_for_msr(vcpu, MSR_IA32_PL2_SSP, MSR_TYPE_RW, incpt); +} + static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -7409,6 +7435,9 @@ static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) /* Refresh #PF interception to account for MAXPHYADDR changes. */ update_exception_bitmap(vcpu); + + if (kvm_cet_supported()) + vmx_update_intercept_for_cet_msr(vcpu); } static __init void vmx_set_cpu_caps(void)