All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zide Chen <zide.chen@intel.com>
To: Sean Christopherson <seanjc@google.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	Jim Mattson <jmattson@google.com>,
	Mingwei Zhang <mizhang@google.com>,
	Zide Chen <zide.chen@intel.com>,
	Das Sandipan <Sandipan.Das@amd.com>,
	Shukla Manali <Manali.Shukla@amd.com>,
	Dapeng Mi <dapeng1.mi@linux.intel.com>,
	Falcon Thomas <thomas.falcon@intel.com>,
	Xudong Hao <xudong.hao@intel.com>
Subject: [PATCH 04/15] KVM: x86/pmu: Add PMC bitmap accessor helpers
Date: Tue,  7 Jul 2026 11:33:54 -0700	[thread overview]
Message-ID: <20260707183405.15571-5-zide.chen@intel.com> (raw)
In-Reply-To: <20260707183405.15571-1-zide.chen@intel.com>

pmu->nr_arch_{gp,fixed}_counters is not able to represent that a PMU
may include non-contiguous GP or fixed counters.

pmu->all_valid_pmc_mask already holds a bitmap indicating both fixed
and general-purpose counters, and loops over valid counters can be
done via pmu->all_valid_pmc_mask alone. Extend it to a union so that
the u64 alias is available for convenient mask arithmetic operations.

Add the necessary helpers to prepare for bitmap-based PMC counter
implementation.

No functional change intended.

Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
---
 arch/x86/include/asm/kvm_host.h |  5 ++-
 arch/x86/kvm/pmu.h              | 55 +++++++++++++++++++++++++++++----
 2 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 395b6f20e9ac..f648dc168685 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -643,7 +643,10 @@ struct kvm_pmu {
 		DECLARE_BITMAP(reprogram_pmi, X86_PMC_IDX_MAX);
 		atomic64_t __reprogram_pmi;
 	};
-	DECLARE_BITMAP(all_valid_pmc_mask, X86_PMC_IDX_MAX);
+	union {
+		DECLARE_BITMAP(all_valid_pmc_mask, X86_PMC_IDX_MAX);
+		u64 all_valid_pmc_mask64;
+	};
 	DECLARE_BITMAP(pmc_in_use, X86_PMC_IDX_MAX);
 
 	DECLARE_BITMAP(pmc_counting_instructions, X86_PMC_IDX_MAX);
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index cdbefda844b9..95dc95a9ae37 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -88,6 +88,32 @@ static inline bool kvm_vcpu_has_mediated_pmu(struct kvm_vcpu *vcpu)
 	return enable_mediated_pmu && vcpu_to_pmu(vcpu)->version;
 }
 
+static inline unsigned long kvm_gp_pmc_mask(struct kvm_pmu *pmu)
+{
+	return pmu->all_valid_pmc_mask64 &
+	       GENMASK_ULL(KVM_MAX_NR_GP_COUNTERS - 1, 0);
+}
+
+static inline unsigned long kvm_fixed_pmc_mask(struct kvm_pmu *pmu)
+{
+	return (pmu->all_valid_pmc_mask64 >> KVM_FIXED_PMC_BASE_IDX) &
+		GENMASK_ULL(KVM_MAX_NR_FIXED_COUNTERS - 1, 0);
+}
+
+static inline bool kvm_gp_pmc_supported(struct kvm_pmu *pmu, unsigned int idx)
+{
+	unsigned long bitmap = kvm_gp_pmc_mask(pmu);
+
+	return idx < KVM_MAX_NR_GP_COUNTERS && test_bit(idx, &bitmap);
+}
+
+static inline bool kvm_fixed_pmc_supported(struct kvm_pmu *pmu, unsigned int idx)
+{
+	unsigned long bitmap = kvm_fixed_pmc_mask(pmu);
+
+	return idx < KVM_MAX_NR_FIXED_COUNTERS && test_bit(idx, &bitmap);
+}
+
 /*
  * KVM tracks all counters in 64-bit bitmaps, with general purpose counters
  * mapped to bits 31:0 and fixed counters mapped to 63:32, e.g. fixed counter 0
@@ -104,11 +130,11 @@ static inline bool kvm_vcpu_has_mediated_pmu(struct kvm_vcpu *vcpu)
  */
 static inline struct kvm_pmc *kvm_pmc_idx_to_pmc(struct kvm_pmu *pmu, int idx)
 {
-	if (idx < pmu->nr_arch_gp_counters)
+	if (kvm_gp_pmc_supported(pmu, idx))
 		return &pmu->gp_counters[idx];
 
 	idx -= KVM_FIXED_PMC_BASE_IDX;
-	if (idx >= 0 && idx < pmu->nr_arch_fixed_counters)
+	if (kvm_fixed_pmc_supported(pmu, idx))
 		return &pmu->fixed_counters[idx];
 
 	return NULL;
@@ -120,6 +146,17 @@ static inline struct kvm_pmc *kvm_pmc_idx_to_pmc(struct kvm_pmu *pmu, int idx)
 			continue;				\
 		else						\
 
+/*
+ * @mask must be an lvalue of type unsigned long because for_each_set_bit()
+ * takes its address.
+ *
+ * @type is token-pasted into KVM_MAX_NR_##type##_COUNTERS to match one of the
+ * counter defines, e.g. GP, FIXED, AMD_GP, INTEL_GP, or INTEL_FIXED. This
+ * reflects what KVM supports, not the underlying host's PMU capabilities.
+ */
+#define kvm_for_each_set_pmc_idx(i, mask, type)		\
+	for_each_set_bit((i), &(mask), KVM_MAX_NR_##type##_COUNTERS)
+
 static inline u64 pmc_bitmask(struct kvm_pmc *pmc)
 {
 	struct kvm_pmu *pmu = pmc_to_pmu(pmc);
@@ -168,9 +205,12 @@ static inline bool kvm_valid_perf_global_ctrl(struct kvm_pmu *pmu,
 static inline struct kvm_pmc *get_gp_pmc(struct kvm_pmu *pmu, u32 msr,
 					 u32 base)
 {
-	if (msr >= base && msr < base + pmu->nr_arch_gp_counters) {
+	if (msr >= base && msr < base + KVM_MAX_NR_GP_COUNTERS) {
 		u32 index = array_index_nospec(msr - base,
-					       pmu->nr_arch_gp_counters);
+					       KVM_MAX_NR_GP_COUNTERS);
+
+		if (!kvm_gp_pmc_supported(pmu, index))
+			return NULL;
 
 		return &pmu->gp_counters[index];
 	}
@@ -183,9 +223,12 @@ static inline struct kvm_pmc *get_fixed_pmc(struct kvm_pmu *pmu, u32 msr)
 {
 	int base = MSR_CORE_PERF_FIXED_CTR0;
 
-	if (msr >= base && msr < base + pmu->nr_arch_fixed_counters) {
+	if (msr >= base && msr < base + KVM_MAX_NR_FIXED_COUNTERS) {
 		u32 index = array_index_nospec(msr - base,
-					       pmu->nr_arch_fixed_counters);
+					       KVM_MAX_NR_FIXED_COUNTERS);
+
+		if (!kvm_fixed_pmc_supported(pmu, index))
+			return NULL;
 
 		return &pmu->fixed_counters[index];
 	}
-- 
2.54.0


  parent reply	other threads:[~2026-07-07 18:43 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-07 18:33 [PATCH 00/15] KVM: x86/pmu: Add mediated vPMU PerfMon v5 support Zide Chen
2026-07-07 18:33 ` [PATCH 01/15] KVM: x86/pmu: Remove redundant Perf Global Status MSR bit definitions Zide Chen
2026-07-07 18:33 ` [PATCH 02/15] KVM: x86/pmu: Rename all_valid_pmc_idx to all_valid_pmc_mask Zide Chen
2026-07-07 18:33 ` [PATCH 03/15] KVM: x86/pmu: Rename reserved_bits to eventsel_rsvd in kvm_pmu Zide Chen
2026-07-07 18:33 ` Zide Chen [this message]
2026-07-07 18:33 ` [PATCH 05/15] KVM: x86/pmu: Drop nr_arch_{gp,fixed}_counters from kvm_pmu Zide Chen
2026-07-07 18:33 ` [PATCH 06/15] KVM: x86/pmu: Expose kvm_host_pmu to vendor modules Zide Chen
2026-07-07 18:33 ` [PATCH 07/15] perf/x86: Plumb counter bitmap from x86_pmu to x86_pmu_cap Zide Chen
2026-07-07 18:33 ` [PATCH 08/15] KVM: x86/pmu: Switch to bitmask-based KVM PMU capabilities Zide Chen
2026-07-07 18:33 ` [PATCH 09/15] perf/x86: Remove num_counters_{gp,fixed} from x86_pmu_capability Zide Chen
2026-07-07 18:34 ` [PATCH 10/15] KVM: x86/pmu: Emulate the GLOBAL_STATUS_SET and GLOBAL_INUSE MSRs Zide Chen
2026-07-07 18:34 ` [PATCH 11/15] KVM: x86/pmu: Emulate streamlined Freeze-LBR-on-PMI Zide Chen
2026-07-07 18:34 ` [PATCH 12/15] KVM: x86/pmu: Populate CPUID.0AH:ECX fixed-counter bitmap Zide Chen
2026-07-07 18:34 ` [PATCH 13/15] KVM: x86/pmu: Ignore AnyThread bit if CPUID.0AH:EDX[15] is not set Zide Chen
2026-07-07 18:34 ` [PATCH 14/15] KVM: x86/pmu: Advertise PerfMon version 5 on Intel hosts Zide Chen
2026-07-07 18:34 ` [PATCH 15/15] KVM: selftests: Support fixed counters bitmap in pmu_counters_test Zide Chen

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=20260707183405.15571-5-zide.chen@intel.com \
    --to=zide.chen@intel.com \
    --cc=Manali.Shukla@amd.com \
    --cc=Sandipan.Das@amd.com \
    --cc=dapeng1.mi@linux.intel.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=thomas.falcon@intel.com \
    --cc=xudong.hao@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.