If the cpuid10_eax.split.num_counters* from kvm_vcpu_ioctl_set_cpuid2 is larger than the host x86_pmu.num_counters_*, the min_t() is applied. We need do cpuid synchronisation locally for cpuid10 entry to avoid functional ambiguity and it's heavyweight to call kvm_update_cpuid for these simple assignments. Signed-off-by: Like Xu <like.xu@xxxxxxxxxxxxxxx> --- arch/x86/kvm/vmx/pmu_intel.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index 3e9c059099e9..f83b7506dcff 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -266,6 +266,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) struct kvm_cpuid_entry2 *entry; union cpuid10_eax eax; union cpuid10_edx edx; + bool cpuid_update_needed = false; pmu->nr_arch_gp_counters = 0; pmu->nr_arch_fixed_counters = 0; @@ -288,6 +289,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters, x86_pmu.num_counters_gp); + if (pmu->nr_arch_gp_counters != eax.split.num_counters) + cpuid_update_needed = true; pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1; pmu->available_event_types = ~entry->ebx & ((1ull << eax.split.mask_length) - 1); @@ -298,6 +301,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) pmu->nr_arch_fixed_counters = min_t(int, edx.split.num_counters_fixed, x86_pmu.num_counters_fixed); + if (pmu->nr_arch_fixed_counters != edx.split.num_counters_fixed) + cpuid_update_needed = true; pmu->counter_bitmask[KVM_PMC_FIXED] = ((u64)1 << edx.split.bit_width_fixed) - 1; } @@ -317,6 +322,13 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu) (boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) && (entry->ebx & (X86_FEATURE_HLE|X86_FEATURE_RTM))) pmu->reserved_bits ^= HSW_IN_TX|HSW_IN_TX_CHECKPOINTED; + + if (cpuid_update_needed) { + ((union cpuid10_eax *)&entry->eax)->split.num_counters + = pmu->nr_arch_gp_counters; + ((union cpuid10_edx *)&entry->edx)->split.num_counters_fixed + = pmu->nr_arch_fixed_counters; + } } static void intel_pmu_init(struct kvm_vcpu *vcpu) -- 2.21.0