From: "Mi, Dapeng" <dapeng1.mi@linux.intel.com>
To: Zide Chen <zide.chen@intel.com>,
Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Peter Zijlstra <peterz@infradead.org>
Cc: kvm@vger.kernel.org, Andi Kleen <ak@linux.intel.com>,
Jim Mattson <jmattson@google.com>,
Stephane Eranian <eranian@google.com>,
linux-kernel@vger.kernel.org, Mingwei Zhang <mizhang@google.com>,
Das Sandipan <Sandipan.Das@amd.com>,
Shukla Manali <Manali.Shukla@amd.com>,
Xudong Hao <xudong.hao@intel.com>
Subject: Re: [PATCH v2 06/16] KVM: x86/pmu: Drop nr_arch_{gp,fixed}_counters from kvm_pmu
Date: Tue, 1 Sep 2026 11:07:27 +0800 [thread overview]
Message-ID: <2bb5aa22-42f0-4d65-a1f9-572084ba2eec@linux.intel.com> (raw)
In-Reply-To: <20260827223755.143247-7-zide.chen@intel.com>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
On 8/28/2026 6:37 AM, Zide Chen wrote:
> From: Dapeng Mi <dapeng1.mi@linux.intel.com>
>
> This is a preparatory step toward fully bitmap-based PMU capability
> handling. Later patches switch KVM's view of host PMU capabilities from
> counter counts to counter bitmaps.
>
> Populate and use pmc_exists directly when walking guest-visible PMCs,
> instead of relying on pmu->nr_arch_{gp,fixed}_counters as intermediate
> state.
>
> Iterate counters via the newly added pmc_exists based helpers, and
> remove the now-redundant nr_arch_{gp,fixed}_counters fields from struct
> kvm_pmu.
>
> Note: {vmx,svm}_recalc_pmu_msr_intercepts() may leave stale intercepts
> on GP MSRs after CPUID narrowing. This corner case is resolved by the
> following patch: "KVM: x86/pmu: Switch to bitmask-based KVM PMU
> capabilities".
>
> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> Co-developed-by: Zide Chen <zide.chen@intel.com>
> Signed-off-by: Zide Chen <zide.chen@intel.com>
> ---
> v2:
> - Fix AMD legacy PMU MSR intercept handling for guest PMU
> narrowing reconfiguration by adding for_each_clear_bit_from().
> - Re-word the stale interception changelog part.
> ---
> arch/x86/include/asm/kvm_host.h | 2 --
> arch/x86/kvm/pmu.c | 26 +++++++++----------
> arch/x86/kvm/svm/pmu.c | 25 ++++++++----------
> arch/x86/kvm/svm/svm.c | 8 ++++--
> arch/x86/kvm/vmx/nested.c | 6 +++--
> arch/x86/kvm/vmx/pmu_intel.c | 46 ++++++++++++++++++++++-----------
> arch/x86/kvm/vmx/vmx.c | 6 +++--
> 7 files changed, 68 insertions(+), 51 deletions(-)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 49a8a2e9cee0..717ba98c08c9 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -569,8 +569,6 @@ struct kvm_pmc {
>
> struct kvm_pmu {
> u8 version;
> - unsigned nr_arch_gp_counters;
> - unsigned nr_arch_fixed_counters;
> unsigned available_event_types;
> u64 fixed_ctr_ctrl;
> u64 fixed_ctr_ctrl_hw;
> diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
> index 964e74bdaaa7..b0fcd0a538d2 100644
> --- a/arch/x86/kvm/pmu.c
> +++ b/arch/x86/kvm/pmu.c
> @@ -785,8 +785,8 @@ static bool kvm_need_any_pmc_intercept(struct kvm_vcpu *vcpu)
> * KVM's capabilities are constrained based on KVM support, i.e. KVM's
> * capabilities themselves may be a subset of hardware capabilities.
> */
> - return pmu->nr_arch_gp_counters != kvm_host_pmu.num_counters_gp ||
> - pmu->nr_arch_fixed_counters != kvm_host_pmu.num_counters_fixed;
> + return kvm_gp_pmc_mask(pmu) != BIT_ULL(kvm_host_pmu.num_counters_gp) - 1 ||
> + kvm_fixed_pmc_mask(pmu) != BIT_ULL(kvm_host_pmu.num_counters_fixed) - 1;
> }
>
> bool kvm_need_perf_global_ctrl_intercept(struct kvm_vcpu *vcpu)
> @@ -985,8 +985,6 @@ void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
> kvm_pmu_reset(vcpu);
>
> pmu->version = 0;
> - pmu->nr_arch_gp_counters = 0;
> - pmu->nr_arch_fixed_counters = 0;
> pmu->counter_bitmask[KVM_PMC_GP] = 0;
> pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
> /*
> @@ -1014,16 +1012,12 @@ void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
> * in the global controls). Emulate that behavior when refreshing the
> * PMU so that userspace doesn't need to manually set PERF_GLOBAL_CTRL.
> */
> - if (pmu->nr_arch_gp_counters &&
> + if (kvm_gp_pmc_mask(pmu) &&
> (kvm_pmu_has_perf_global_ctrl(pmu) || kvm_vcpu_has_mediated_pmu(vcpu)))
> - pmu->global_ctrl = GENMASK_ULL(pmu->nr_arch_gp_counters - 1, 0);
> + pmu->global_ctrl = kvm_gp_pmc_mask(pmu);
>
> if (kvm_vcpu_has_mediated_pmu(vcpu))
> kvm_pmu_call(write_global_ctrl)(pmu->global_ctrl);
> -
> - bitmap_set(pmu->pmc_exists, 0, pmu->nr_arch_gp_counters);
> - bitmap_set(pmu->pmc_exists, KVM_FIXED_PMC_BASE_IDX,
> - pmu->nr_arch_fixed_counters);
> }
>
> void kvm_pmu_init(struct kvm_vcpu *vcpu)
> @@ -1332,6 +1326,8 @@ static __always_inline u32 gp_eventsel_msr(u32 idx)
> static void kvm_pmu_load_guest_pmcs(struct kvm_vcpu *vcpu)
> {
> struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> + unsigned long fixed_mask = kvm_fixed_pmc_mask(pmu);
> + unsigned long gp_mask = kvm_gp_pmc_mask(pmu);
> struct kvm_pmc *pmc;
> u32 i;
>
> @@ -1340,14 +1336,14 @@ static void kvm_pmu_load_guest_pmcs(struct kvm_vcpu *vcpu)
> * is intercepted if hardware has counters that aren't visible to the
> * guest (KVM will inject #GP as appropriate).
> */
> - for (i = 0; i < pmu->nr_arch_gp_counters; i++) {
> + kvm_for_each_gp_counter(i, gp_mask) {
> pmc = &pmu->gp_counters[i];
>
> if (pmc->counter != rdpmc(i))
> wrmsrq(gp_counter_msr(i), pmc->counter);
> wrmsrq(gp_eventsel_msr(i), pmc->eventsel_hw);
> }
> - for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
> + kvm_for_each_fixed_counter(i, fixed_mask) {
> pmc = &pmu->fixed_counters[i];
>
> if (pmc->counter != rdpmc(INTEL_PMC_FIXED_RDPMC_BASE | i))
> @@ -1390,6 +1386,8 @@ void kvm_mediated_pmu_load(struct kvm_vcpu *vcpu)
> static void kvm_pmu_put_guest_pmcs(struct kvm_vcpu *vcpu)
> {
> struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> + unsigned long fixed_mask = kvm_fixed_pmc_mask(pmu);
> + unsigned long gp_mask = kvm_gp_pmc_mask(pmu);
> struct kvm_pmc *pmc;
> u32 i;
>
> @@ -1397,7 +1395,7 @@ static void kvm_pmu_put_guest_pmcs(struct kvm_vcpu *vcpu)
> * Clear selectors and counters to ensure hardware doesn't count using
> * guest controls when the host (perf) restores its state.
> */
> - for (i = 0; i < pmu->nr_arch_gp_counters; i++) {
> + kvm_for_each_gp_counter(i, gp_mask) {
> pmc = &pmu->gp_counters[i];
>
> pmc->counter = rdpmc(i);
> @@ -1407,7 +1405,7 @@ static void kvm_pmu_put_guest_pmcs(struct kvm_vcpu *vcpu)
> wrmsrq(gp_eventsel_msr(i), 0);
> }
>
> - for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
> + kvm_for_each_fixed_counter(i, fixed_mask) {
> pmc = &pmu->fixed_counters[i];
>
> pmc->counter = rdpmc(INTEL_PMC_FIXED_RDPMC_BASE | i);
> diff --git a/arch/x86/kvm/svm/pmu.c b/arch/x86/kvm/svm/pmu.c
> index 52224872e0d4..0943ccc1d6b8 100644
> --- a/arch/x86/kvm/svm/pmu.c
> +++ b/arch/x86/kvm/svm/pmu.c
> @@ -27,12 +27,11 @@ enum pmu_type {
>
> static struct kvm_pmc *amd_pmu_get_pmc(struct kvm_pmu *pmu, int pmc_idx)
> {
> - unsigned int num_counters = pmu->nr_arch_gp_counters;
> -
> - if (pmc_idx >= num_counters)
> + if (!kvm_is_gp_pmc_supported(pmu, pmc_idx))
> return NULL;
>
> - return &pmu->gp_counters[array_index_nospec(pmc_idx, num_counters)];
> + pmc_idx = array_index_nospec(pmc_idx, KVM_MAX_NR_AMD_GP_COUNTERS);
> + return &pmu->gp_counters[pmc_idx];
> }
>
> static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr,
> @@ -77,7 +76,7 @@ static int amd_check_rdpmc_early(struct kvm_vcpu *vcpu, unsigned int idx)
> {
> struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
>
> - if (idx >= pmu->nr_arch_gp_counters)
> + if (!kvm_is_gp_pmc_supported(pmu, idx))
> return -EINVAL;
>
> return 0;
> @@ -117,7 +116,7 @@ static bool amd_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
> return pmu->version > 1;
> default:
> if (msr > MSR_F15H_PERF_CTR5 &&
> - msr < MSR_F15H_PERF_CTL0 + 2 * pmu->nr_arch_gp_counters)
> + msr < MSR_F15H_PERF_CTL0 + 2 * hweight_long(kvm_gp_pmc_mask(pmu)))
> return pmu->version > 1;
> break;
> }
> @@ -184,6 +183,7 @@ static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>
> static void amd_pmu_refresh(struct kvm_vcpu *vcpu)
> {
> + unsigned int nr_gp_counters = AMD64_NUM_COUNTERS;
> struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> union cpuid_0x80000022_ebx ebx;
>
> @@ -197,18 +197,16 @@ static void amd_pmu_refresh(struct kvm_vcpu *vcpu)
> BUILD_BUG_ON(x86_feature_cpuid(X86_FEATURE_PERFMON_V2).function != 0x80000022 ||
> x86_feature_cpuid(X86_FEATURE_PERFMON_V2).index);
> ebx.full = kvm_find_cpuid_entry_index(vcpu, 0x80000022, 0)->ebx;
> - pmu->nr_arch_gp_counters = ebx.split.num_core_pmc;
> + nr_gp_counters = ebx.split.num_core_pmc;
> } else if (guest_cpu_cap_has(vcpu, X86_FEATURE_PERFCTR_CORE)) {
> - pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS_CORE;
> - } else {
> - pmu->nr_arch_gp_counters = AMD64_NUM_COUNTERS;
> + nr_gp_counters = AMD64_NUM_COUNTERS_CORE;
> }
>
> - pmu->nr_arch_gp_counters = min_t(unsigned int, pmu->nr_arch_gp_counters,
> - kvm_pmu_cap.num_counters_gp);
> + pmu->pmc_exists64 = (BIT_ULL(nr_gp_counters) - 1) &
> + (BIT_ULL(kvm_pmu_cap.num_counters_gp) - 1);
>
> if (pmu->version > 1) {
> - pmu->global_ctrl_rsvd = ~(BIT_ULL(pmu->nr_arch_gp_counters) - 1);
> + pmu->global_ctrl_rsvd = ~pmu->pmc_exists64;
> pmu->global_status_rsvd = pmu->global_ctrl_rsvd;
> }
>
> @@ -227,7 +225,6 @@ static void amd_pmu_refresh(struct kvm_vcpu *vcpu)
> pmu->raw_event_mask = AMD64_RAW_EVENT_MASK;
> /* not applicable to AMD; but clean them to prevent any fall out */
> pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
> - pmu->nr_arch_fixed_counters = 0;
> }
>
> static void amd_pmu_init(struct kvm_vcpu *vcpu)
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 9d607b98bd06..fb8442a08b63 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -753,18 +753,22 @@ static void svm_recalc_pmu_msr_intercepts(struct kvm_vcpu *vcpu)
> {
> bool intercept = !kvm_vcpu_has_mediated_pmu(vcpu);
> struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> + unsigned long gp_mask = kvm_gp_pmc_mask(pmu);
> int i;
>
> if (!enable_mediated_pmu)
> return;
>
> /* Legacy counters are always available for AMD CPUs with a PMU. */
> - for (i = 0; i < min(pmu->nr_arch_gp_counters, AMD64_NUM_COUNTERS); i++)
> + for_each_set_bit(i, &gp_mask, AMD64_NUM_COUNTERS)
> svm_set_intercept_for_msr(vcpu, MSR_K7_PERFCTR0 + i,
> MSR_TYPE_RW, intercept);
> + for_each_clear_bit(i, &gp_mask, AMD64_NUM_COUNTERS)
> + svm_enable_intercept_for_msr(vcpu, MSR_K7_PERFCTR0 + i,
> + MSR_TYPE_RW);
>
> intercept |= !guest_cpu_cap_has(vcpu, X86_FEATURE_PERFCTR_CORE);
> - for (i = 0; i < pmu->nr_arch_gp_counters; i++)
> + kvm_for_each_gp_counter(i, gp_mask)
> svm_set_intercept_for_msr(vcpu, MSR_F15H_PERF_CTR + 2 * i,
> MSR_TYPE_RW, intercept);
>
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index 7ed79894d11d..0cff369982ae 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -697,6 +697,8 @@ static void nested_vmx_merge_pmu_msr_bitmaps(struct kvm_vcpu *vcpu,
> {
> struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> struct vcpu_vmx *vmx = to_vmx(vcpu);
> + unsigned long gp_mask = kvm_gp_pmc_mask(pmu);
> + unsigned long fixed_mask = kvm_fixed_pmc_mask(pmu);
> int i;
>
> /*
> @@ -706,12 +708,12 @@ static void nested_vmx_merge_pmu_msr_bitmaps(struct kvm_vcpu *vcpu,
> if (!kvm_vcpu_has_mediated_pmu(vcpu))
> return;
>
> - for (i = 0; i < pmu->nr_arch_gp_counters; i++) {
> + kvm_for_each_gp_counter(i, gp_mask) {
> nested_vmx_merge_msr_bitmaps_rw(MSR_IA32_PERFCTR0 + i);
> nested_vmx_merge_msr_bitmaps_rw(MSR_IA32_PMC0 + i);
> }
>
> - for (i = 0; i < pmu->nr_arch_fixed_counters; i++)
> + kvm_for_each_fixed_counter(i, fixed_mask)
> nested_vmx_merge_msr_bitmaps_rw(MSR_CORE_PERF_FIXED_CTR0 + i);
>
> nested_vmx_merge_msr_bitmaps_rw(MSR_CORE_PERF_GLOBAL_CTRL);
> diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
> index 9fdae437e569..926d1c57f8bf 100644
> --- a/arch/x86/kvm/vmx/pmu_intel.c
> +++ b/arch/x86/kvm/vmx/pmu_intel.c
> @@ -66,12 +66,13 @@ static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
> * hardware, e.g. to ensure the event filter is enforced.
> */
> u64 old_fixed_ctr_ctrl = pmu->fixed_ctr_ctrl_hw;
> + unsigned long fixed_mask = kvm_fixed_pmc_mask(pmu);
> struct kvm_pmc *pmc;
> int i;
>
> pmu->fixed_ctr_ctrl = data;
> pmu->fixed_ctr_ctrl_hw = data;
> - for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
> + kvm_for_each_fixed_counter(i, fixed_mask) {
> u8 new_ctrl = fixed_ctrl_field(data, i);
> u8 old_ctrl = fixed_ctrl_field(old_fixed_ctr_ctrl, i);
>
> @@ -107,6 +108,8 @@ static struct kvm_pmc *intel_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu,
> if (WARN_ON_ONCE(!pmu->version))
> return NULL;
>
> + idx &= INTEL_RDPMC_INDEX_MASK;
> +
> /*
> * General Purpose (GP) PMCs are supported on all PMUs, and fixed PMCs
> * are supported on all architectural PMUs, i.e. on all virtual PMUs
> @@ -117,23 +120,25 @@ static struct kvm_pmc *intel_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu,
> */
> switch (type) {
> case INTEL_RDPMC_FIXED:
> + if (!kvm_is_fixed_pmc_supported(pmu, idx))
> + return NULL;
> +
> counters = pmu->fixed_counters;
> - num_counters = pmu->nr_arch_fixed_counters;
> + num_counters = KVM_MAX_NR_INTEL_FIXED_COUNTERS;
> bitmask = pmu->counter_bitmask[KVM_PMC_FIXED];
> break;
> case INTEL_RDPMC_GP:
> + if (!kvm_is_gp_pmc_supported(pmu, idx))
> + return NULL;
> +
> counters = pmu->gp_counters;
> - num_counters = pmu->nr_arch_gp_counters;
> + num_counters = KVM_MAX_NR_INTEL_GP_COUNTERS;
> bitmask = pmu->counter_bitmask[KVM_PMC_GP];
> break;
> default:
> return NULL;
> }
>
> - idx &= INTEL_RDPMC_INDEX_MASK;
> - if (idx >= num_counters)
> - return NULL;
> -
> *mask &= bitmask;
> return &counters[array_index_nospec(idx, num_counters)];
> }
> @@ -492,9 +497,10 @@ static __always_inline u64 intel_get_fixed_pmc_eventsel(unsigned int index)
>
> static void intel_pmu_enable_fixed_counter_bits(struct kvm_pmu *pmu, u64 bits)
> {
> + unsigned long fixed_mask = kvm_fixed_pmc_mask(pmu);
> int i;
>
> - for (i = 0; i < pmu->nr_arch_fixed_counters; i++)
> + kvm_for_each_fixed_counter(i, fixed_mask)
> pmu->fixed_ctr_ctrl_rsvd &= ~intel_fixed_bits_by_idx(i, bits);
> }
>
> @@ -506,6 +512,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
> union cpuid10_eax eax;
> union cpuid10_edx edx;
> u64 perf_capabilities;
> + u64 fixed_cntr_mask;
> + int nr_gp_counters;
> u64 counter_rsvd;
>
> if (!lbr_desc)
> @@ -532,8 +540,6 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
> if (!pmu->version)
> return;
>
> - pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters,
> - kvm_pmu_cap.num_counters_gp);
> eax.split.bit_width = min_t(int, eax.split.bit_width,
> kvm_pmu_cap.bit_width_gp);
> pmu->counter_bitmask[KVM_PMC_GP] = BIT_ULL(eax.split.bit_width) - 1;
> @@ -541,6 +547,17 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
> kvm_pmu_cap.events_mask_len);
> pmu->available_event_types = ~entry->ebx & (BIT_ULL(eax.split.mask_length) - 1);
>
> + fixed_cntr_mask = BIT_ULL(edx.split.num_counters_fixed) - 1;
> + fixed_cntr_mask &= BIT_ULL(kvm_pmu_cap.num_counters_fixed) - 1;
> +
> + /*
> + * The number of counters comes from guest CPUID data. Clamp the value
> + * to avoid a shift-by-64 in BIT_ULL().
> + */
> + nr_gp_counters = min_t(int, eax.split.num_counters, X86_PMC_IDX_MAX - 1);
> + pmu->pmc_exists64 = (BIT_ULL(nr_gp_counters) - 1) &
> + (BIT_ULL(kvm_pmu_cap.num_counters_gp) - 1);
> +
> entry = kvm_find_cpuid_entry_index(vcpu, 7, 0);
> if (entry &&
> (boot_cpu_has(X86_FEATURE_HLE) || boot_cpu_has(X86_FEATURE_RTM)) &&
> @@ -562,8 +579,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
> if (pmu->version == 1)
> return;
>
> - pmu->nr_arch_fixed_counters = min_t(int, edx.split.num_counters_fixed,
> - kvm_pmu_cap.num_counters_fixed);
> + pmu->pmc_exists64 |= fixed_cntr_mask << INTEL_PMC_IDX_FIXED;
> edx.split.bit_width_fixed = min_t(int, edx.split.bit_width_fixed,
> kvm_pmu_cap.bit_width_fixed);
> pmu->counter_bitmask[KVM_PMC_FIXED] = BIT_ULL(edx.split.bit_width_fixed) - 1;
> @@ -572,8 +588,8 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
> INTEL_FIXED_0_USER |
> INTEL_FIXED_0_ENABLE_PMI);
>
> - counter_rsvd = ~((BIT_ULL(pmu->nr_arch_gp_counters) - 1) |
> - ((BIT_ULL(pmu->nr_arch_fixed_counters) - 1) << KVM_FIXED_PMC_BASE_IDX));
> + counter_rsvd = ~(kvm_gp_pmc_mask(pmu) |
> + ((u64)kvm_fixed_pmc_mask(pmu) << KVM_FIXED_PMC_BASE_IDX));
> pmu->global_ctrl_rsvd = counter_rsvd;
>
> /*
> @@ -596,7 +612,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
> pmu->pebs_data_cfg_rsvd = ~0xff00000full;
> intel_pmu_enable_fixed_counter_bits(pmu, ICL_FIXED_0_ADAPTIVE);
> } else {
> - pmu->pebs_enable_rsvd = ~(BIT_ULL(pmu->nr_arch_gp_counters) - 1);
> + pmu->pebs_enable_rsvd = ~kvm_gp_pmc_mask(pmu);
> }
> }
> }
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index d3789b2ee18e..be994adbd954 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -4230,6 +4230,8 @@ static void vmx_recalc_pmu_msr_intercepts(struct kvm_vcpu *vcpu)
> bool has_mediated_pmu = kvm_vcpu_has_mediated_pmu(vcpu);
> struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
> struct vcpu_vmx *vmx = to_vmx(vcpu);
> + unsigned long fixed_mask = kvm_fixed_pmc_mask(pmu);
> + unsigned long gp_mask = kvm_gp_pmc_mask(pmu);
> bool intercept = !has_mediated_pmu;
> int i;
>
> @@ -4250,7 +4252,7 @@ static void vmx_recalc_pmu_msr_intercepts(struct kvm_vcpu *vcpu)
>
> vm_exit_controls_changebit(vmx, vm_exit_controls_bits, has_mediated_pmu);
>
> - for (i = 0; i < pmu->nr_arch_gp_counters; i++) {
> + kvm_for_each_gp_counter(i, gp_mask) {
> vmx_set_intercept_for_msr(vcpu, MSR_IA32_PERFCTR0 + i,
> MSR_TYPE_RW, intercept);
> vmx_set_intercept_for_msr(vcpu, MSR_IA32_PMC0 + i, MSR_TYPE_RW,
> @@ -4263,7 +4265,7 @@ static void vmx_recalc_pmu_msr_intercepts(struct kvm_vcpu *vcpu)
> MSR_TYPE_RW, true);
> }
>
> - for (i = 0; i < pmu->nr_arch_fixed_counters; i++)
> + kvm_for_each_fixed_counter(i, fixed_mask)
> vmx_set_intercept_for_msr(vcpu, MSR_CORE_PERF_FIXED_CTR0 + i,
> MSR_TYPE_RW, intercept);
> for ( ; i < kvm_pmu_cap.num_counters_fixed; i++)
next prev parent reply other threads:[~2026-09-01 3:07 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-27 22:37 [PATCH] KVM: x86/pmu: Add mediated vPMU PerfMon v5 support Zide Chen
2026-08-27 22:37 ` [PATCH v2 01/16] KVM: x86/pmu: Remove redundant Perf Global Status MSR bit definitions Zide Chen
2026-08-27 22:57 ` sashiko-bot
2026-08-28 13:51 ` Chen, Zide
2026-09-01 2:07 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 02/16] KVM: x86/pmu: Rename all_valid_pmc_idx to pmc_exists Zide Chen
2026-09-01 2:09 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 03/16] KVM: x86/pmu: Rename reserved_bits to eventsel_rsvd in kvm_pmu Zide Chen
2026-09-01 2:17 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 04/16] KVM: x86/pmu: Gate BUFFER_OVF reserved bit on guest DS Zide Chen
2026-09-01 2:30 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 05/16] KVM: x86/pmu: Add PMC bitmap accessor helpers Zide Chen
2026-09-01 2:43 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 06/16] KVM: x86/pmu: Drop nr_arch_{gp,fixed}_counters from kvm_pmu Zide Chen
2026-09-01 3:07 ` Mi, Dapeng [this message]
2026-08-27 22:37 ` [PATCH v2 07/16] KVM: x86/pmu: Expose kvm_host_pmu to vendor modules Zide Chen
2026-09-01 3:08 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 08/16] perf/x86: Plumb counter bitmap from x86_pmu to x86_pmu_cap Zide Chen
2026-08-27 22:37 ` [PATCH v2 09/16] KVM: x86/pmu: Switch to bitmask-based KVM PMU capabilities Zide Chen
2026-09-01 3:32 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 10/16] perf/x86: Remove num_counters_{gp,fixed} from x86_pmu_capability Zide Chen
2026-08-27 22:37 ` [PATCH v2 11/16] KVM: x86/pmu: Emulate the GLOBAL_STATUS_SET and GLOBAL_INUSE MSRs Zide Chen
2026-08-27 23:05 ` sashiko-bot
2026-08-28 20:22 ` Chen, Zide
2026-09-01 6:45 ` Mi, Dapeng
2026-09-01 14:20 ` Chen, Zide
2026-09-02 0:44 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 12/16] KVM: x86/pmu: Populate CPUID.0AH:ECX fixed-counter bitmap Zide Chen
2026-09-01 6:50 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 13/16] KVM: x86/pmu: Factor out fixed counter control bit calculation Zide Chen
2026-09-01 6:57 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 14/16] KVM: x86/pmu: Ignore AnyThread bit if CPUID.0AH:EDX[15] is set Zide Chen
2026-09-01 8:01 ` Mi, Dapeng
2026-08-27 22:37 ` [PATCH v2 15/16] KVM: x86/pmu: Advertise PerfMon version 5 on Intel hosts Zide Chen
2026-08-27 22:37 ` [PATCH v2 16/16] KVM: selftests: Support fixed counters bitmap in pmu_counters_test Zide Chen
2026-08-29 9:30 ` [PATCH] KVM: x86/pmu: Add mediated vPMU PerfMon v5 support Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2bb5aa22-42f0-4d65-a1f9-572084ba2eec@linux.intel.com \
--to=dapeng1.mi@linux.intel.com \
--cc=Manali.Shukla@amd.com \
--cc=Sandipan.Das@amd.com \
--cc=ak@linux.intel.com \
--cc=eranian@google.com \
--cc=jmattson@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mizhang@google.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=seanjc@google.com \
--cc=xudong.hao@intel.com \
--cc=zide.chen@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox