From: Lai Jiangshan <jiangshan.ljs@xxxxxxxxxxxx> The MSR_TSC_AUX is allowed to be modified by the guest to support RDTSCP/RDPID in the guest. However, the MSR_IA32_FEAT_CTRL is not fully supported for the guest at this time; only the FEAT_CTL_LOCKED bit is valid for the guest. Signed-off-by: Lai Jiangshan <jiangshan.ljs@xxxxxxxxxxxx> Signed-off-by: Hou Wenlong <houwenlong.hwl@xxxxxxxxxxxx> --- arch/x86/kvm/pvm/pvm.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/arch/x86/kvm/pvm/pvm.c b/arch/x86/kvm/pvm/pvm.c index fd3d6f7301af..a32d2728eb02 100644 --- a/arch/x86/kvm/pvm/pvm.c +++ b/arch/x86/kvm/pvm/pvm.c @@ -854,6 +854,32 @@ static void pvm_msr_filter_changed(struct kvm_vcpu *vcpu) /* Accesses to MSRs are emulated in hypervisor, nothing to do here. */ } +static inline bool is_pvm_feature_control_msr_valid(struct vcpu_pvm *pvm, + struct msr_data *msr_info) +{ + /* + * currently only FEAT_CTL_LOCKED bit is valid, maybe + * vmx, sgx and mce associated bits can be valid when those features + * are supported for guest. + */ + u64 valid_bits = pvm->msr_ia32_feature_control_valid_bits; + + if (!msr_info->host_initiated && + (pvm->msr_ia32_feature_control & FEAT_CTL_LOCKED)) + return false; + + return !(msr_info->data & ~valid_bits); +} + +static void pvm_update_uret_msr(struct vcpu_pvm *pvm, unsigned int slot, + u64 data, u64 mask) +{ + preempt_disable(); + if (pvm->loaded_cpu_state) + kvm_set_user_return_msr(slot, data, mask); + preempt_enable(); +} + /* * Reads an msr value (of 'msr_index') into 'msr_info'. * Returns 0 on success, non-0 otherwise. @@ -899,9 +925,15 @@ static int pvm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_IA32_SYSENTER_ESP: msr_info->data = pvm->unused_MSR_IA32_SYSENTER_ESP; break; + case MSR_TSC_AUX: + msr_info->data = pvm->msr_tsc_aux; + break; case MSR_IA32_DEBUGCTLMSR: msr_info->data = 0; break; + case MSR_IA32_FEAT_CTL: + msr_info->data = pvm->msr_ia32_feature_control; + break; case MSR_PVM_VCPU_STRUCT: msr_info->data = pvm->msr_vcpu_struct; break; @@ -988,9 +1020,18 @@ static int pvm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_IA32_SYSENTER_ESP: pvm->unused_MSR_IA32_SYSENTER_ESP = data; break; + case MSR_TSC_AUX: + pvm->msr_tsc_aux = data; + pvm_update_uret_msr(pvm, 1, data, -1ull); + break; case MSR_IA32_DEBUGCTLMSR: /* It is ignored now. */ break; + case MSR_IA32_FEAT_CTL: + if (!is_intel || !is_pvm_feature_control_msr_valid(pvm, msr_info)) + return 1; + pvm->msr_ia32_feature_control = data; + break; case MSR_MISC_FEATURES_ENABLES: ret = kvm_set_msr_common(vcpu, msr_info); if (!ret) -- 2.19.1.6.gb485710b