On 02/03/19 03:45, Fenghua Yu wrote: > From: Xiaoyao Li <xiaoyao.li@xxxxxxxxxxxxxxx> > > MSR IA32_CORE_CAPABILITY is a feature-enumerating MSR, bit 5 of which > reports the capability of enabling detection of split locks (will be > supported on future processors based on Tremont microarchitecture and > later). > > Please check the latest Intel Architecture Instruction Set Extensions > and Future Features Programming Reference for more detailed information > on the MSR and the split lock bit. > > 1. Expose it to user space as a feature-enumerating MSR, so that user > space can query it. > > 2. Emualte MSR_IA32_CORE_CAPABILITY with vmx->core_capability. And add the > get and set handler of MSR_IA32_CORE_CAPABILITY. > For uesrspace, it can set this MSR when customizing features of guest, > also it can read the value of this MSR of guest. > For guest, as it's a feature-enumerating MSR, guest only can read it. > > Signed-off-by: Xiaoyao Li <xiaoyao.li@xxxxxxxxxxxxxxx> > Signed-off-by: Fenghua Yu <fenghua.yu@xxxxxxxxx> > --- > arch/x86/include/asm/kvm_host.h | 1 + > arch/x86/kvm/vmx/vmx.c | 23 +++++++++++++++++++++++ > arch/x86/kvm/vmx/vmx.h | 1 + > arch/x86/kvm/x86.c | 17 ++++++++++++++++- > 4 files changed, 41 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index 180373360e34..208f15570d17 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -1527,6 +1527,7 @@ int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, > unsigned long icr, int op_64_bit); > > u64 kvm_get_arch_capabilities(void); > +u64 kvm_get_core_capability(void); > void kvm_define_shared_msr(unsigned index, u32 msr); > int kvm_set_shared_msr(unsigned index, u64 val, u64 mask); > > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c > index 30a6bcd735ec..3e03c6e1e558 100644 > --- a/arch/x86/kvm/vmx/vmx.c > +++ b/arch/x86/kvm/vmx/vmx.c > @@ -1679,6 +1679,12 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) > > msr_info->data = to_vmx(vcpu)->spec_ctrl; > break; > + case MSR_IA32_CORE_CAPABILITY: > + if (!msr_info->host_initiated && > + !guest_cpuid_has(vcpu, X86_FEATURE_CORE_CAPABILITY)) > + return 1; > + msr_info->data = vmx->core_capability; > + break; > case MSR_IA32_ARCH_CAPABILITIES: > if (!msr_info->host_initiated && > !guest_cpuid_has(vcpu, X86_FEATURE_ARCH_CAPABILITIES)) > @@ -1891,6 +1897,21 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) > vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, MSR_IA32_PRED_CMD, > MSR_TYPE_W); > break; > + case MSR_IA32_CORE_CAPABILITY: > + if (!msr_info->host_initiated) > + return 1; > + if (data & ~CORE_CAP_SPLIT_LOCK_DETECT) > + return 1; > + > + /* > + * Since AC split lock is a hardware feature, and there is no > + * software emulation yet, we cannot enable it for guest if > + * host hardware doesn't support it. > + */ > + if (!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) > + data &= ~CORE_CAP_SPLIT_LOCK_DETECT; > + vmx->core_capability = data; > + break; > case MSR_IA32_ARCH_CAPABILITIES: > if (!msr_info->host_initiated) > return 1; > @@ -4083,6 +4104,8 @@ static void vmx_vcpu_setup(struct vcpu_vmx *vmx) > ++vmx->nmsrs; > } > > + vmx->core_capability = kvm_get_core_capability(); > + > vmx->arch_capabilities = kvm_get_arch_capabilities(); > > vm_exit_controls_init(vmx, vmx_vmexit_ctrl()); > diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h > index 0ac0a64c7790..cc22379991f3 100644 > --- a/arch/x86/kvm/vmx/vmx.h > +++ b/arch/x86/kvm/vmx/vmx.h > @@ -191,6 +191,7 @@ struct vcpu_vmx { > u64 msr_guest_kernel_gs_base; > #endif > > + u64 core_capability; > u64 arch_capabilities; > u64 spec_ctrl; > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 941f932373d0..c3c9e3f2d08a 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -1125,7 +1125,8 @@ static u32 msrs_to_save[] = { > #endif > MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA, > MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX, > - MSR_IA32_SPEC_CTRL, MSR_IA32_ARCH_CAPABILITIES, > + MSR_IA32_SPEC_CTRL, MSR_IA32_CORE_CAPABILITY, > + MSR_IA32_ARCH_CAPABILITIES, > MSR_IA32_RTIT_CTL, MSR_IA32_RTIT_STATUS, MSR_IA32_RTIT_CR3_MATCH, > MSR_IA32_RTIT_OUTPUT_BASE, MSR_IA32_RTIT_OUTPUT_MASK, > MSR_IA32_RTIT_ADDR0_A, MSR_IA32_RTIT_ADDR0_B, > @@ -1197,11 +1198,22 @@ static u32 msr_based_features[] = { > > MSR_F10H_DECFG, > MSR_IA32_UCODE_REV, > + MSR_IA32_CORE_CAPABILITY, > MSR_IA32_ARCH_CAPABILITIES, > }; > > static unsigned int num_msr_based_features; > > +u64 kvm_get_core_capability(void) > +{ > + u64 data; > + > + rdmsrl_safe(MSR_IA32_CORE_CAPABILITY, &data); This patch should be merged with the previous patch. Also here you should add: data &= CORE_CAP_SPLIT_LOCK_DETECT; so that non-virtualizable features are hidden and if (boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) data |= CORE_CAP_SPLIT_LOCK_DETECT; so that userspace gets "for free" the FMS list that will be added later to the kernel. Thanks, Paolo > + > + return data; > +} > +EXPORT_SYMBOL_GPL(kvm_get_core_capability); > + > u64 kvm_get_arch_capabilities(void) > { > u64 data; > @@ -1227,6 +1239,9 @@ EXPORT_SYMBOL_GPL(kvm_get_arch_capabilities); > static int kvm_get_msr_feature(struct kvm_msr_entry *msr) > { > switch (msr->index) { > + case MSR_IA32_CORE_CAPABILITY: > + msr->data = kvm_get_core_capability(); > + break; > case MSR_IA32_ARCH_CAPABILITIES: > msr->data = kvm_get_arch_capabilities(); > break; >