Message ID | 20220601031925.59693-1-likexu@tencent.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/3] KVM: x86/pmu: Accept 0 for absent PMU MSRs when host-initiated if !enable_pmu | expand |
On 6/1/22 05:19, Like Xu wrote: > From: Like Xu <likexu@tencent.com> > > Whenever an MSR is part of KVM_GET_MSR_INDEX_LIST, as is the case for > MSR_K7_EVNTSEL0 or MSR_F15H_PERF_CTL0, it has to be always retrievable > and settable with KVM_GET_MSR and KVM_SET_MSR. > > Accept a zero value for these MSRs to obey the contract. > > Signed-off-by: Like Xu <likexu@tencent.com> > --- > Note, if !enable_pmu, it is easy to reproduce and verify it with selftest. > > arch/x86/kvm/pmu.c | 8 ++++++++ > arch/x86/kvm/svm/pmu.c | 11 ++++++++++- > 2 files changed, 18 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c > index 7a74691de223..3575a3746bf9 100644 > --- a/arch/x86/kvm/pmu.c > +++ b/arch/x86/kvm/pmu.c > @@ -439,11 +439,19 @@ static void kvm_pmu_mark_pmc_in_use(struct kvm_vcpu *vcpu, u32 msr) > > int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) > { > + if (msr_info->host_initiated && !vcpu->kvm->arch.enable_pmu) { > + msr_info->data = 0; > + return 0; > + } > + > return static_call(kvm_x86_pmu_get_msr)(vcpu, msr_info); > } > > int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) > { > + if (msr_info->host_initiated && !vcpu->kvm->arch.enable_pmu) > + return !!msr_info->data; > + > kvm_pmu_mark_pmc_in_use(vcpu, msr_info->index); > return static_call(kvm_x86_pmu_set_msr)(vcpu, msr_info); > } > diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c > index 256244b8f89c..fe520b2649b5 100644 > --- a/arch/x86/kvm/svm/pmu.c > +++ b/arch/x86/kvm/svm/pmu.c > @@ -182,7 +182,16 @@ static struct kvm_pmc *amd_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu, > static bool amd_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr, bool host_initiated) > { > /* All MSRs refer to exactly one PMC, so msr_idx_to_pmc is enough. */ > - return false; > + if (!host_initiated) > + return false; > + > + switch (msr) { > + case MSR_K7_EVNTSEL0 ... MSR_K7_PERFCTR3: > + case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5: > + return true; > + default: > + return false; > + } > } > > static struct kvm_pmc *amd_msr_idx_to_pmc(struct kvm_vcpu *vcpu, u32 msr) Queued all three, thanks. Paolo
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 7a74691de223..3575a3746bf9 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -439,11 +439,19 @@ static void kvm_pmu_mark_pmc_in_use(struct kvm_vcpu *vcpu, u32 msr) int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { + if (msr_info->host_initiated && !vcpu->kvm->arch.enable_pmu) { + msr_info->data = 0; + return 0; + } + return static_call(kvm_x86_pmu_get_msr)(vcpu, msr_info); } int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) { + if (msr_info->host_initiated && !vcpu->kvm->arch.enable_pmu) + return !!msr_info->data; + kvm_pmu_mark_pmc_in_use(vcpu, msr_info->index); return static_call(kvm_x86_pmu_set_msr)(vcpu, msr_info); } diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c index 256244b8f89c..fe520b2649b5 100644 --- a/arch/x86/kvm/svm/pmu.c +++ b/arch/x86/kvm/svm/pmu.c @@ -182,7 +182,16 @@ static struct kvm_pmc *amd_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu, static bool amd_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr, bool host_initiated) { /* All MSRs refer to exactly one PMC, so msr_idx_to_pmc is enough. */ - return false; + if (!host_initiated) + return false; + + switch (msr) { + case MSR_K7_EVNTSEL0 ... MSR_K7_PERFCTR3: + case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5: + return true; + default: + return false; + } } static struct kvm_pmc *amd_msr_idx_to_pmc(struct kvm_vcpu *vcpu, u32 msr)