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, 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>,
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>,
Xudong Hao <xudong.hao@intel.com>
Subject: [PATCH v2 06/16] KVM: x86/pmu: Drop nr_arch_{gp,fixed}_counters from kvm_pmu
Date: Thu, 27 Aug 2026 15:37:45 -0700 [thread overview]
Message-ID: <20260827223755.143247-7-zide.chen@intel.com> (raw)
In-Reply-To: <20260827223755.143247-1-zide.chen@intel.com>
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++)
--
2.55.0
next prev parent reply other threads:[~2026-08-27 22:48 UTC|newest]
Thread overview: 21+ 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-08-27 22:37 ` [PATCH v2 02/16] KVM: x86/pmu: Rename all_valid_pmc_idx to pmc_exists Zide Chen
2026-08-27 22:37 ` [PATCH v2 03/16] KVM: x86/pmu: Rename reserved_bits to eventsel_rsvd in kvm_pmu Zide Chen
2026-08-27 22:37 ` [PATCH v2 04/16] KVM: x86/pmu: Gate BUFFER_OVF reserved bit on guest DS Zide Chen
2026-08-27 22:37 ` [PATCH v2 05/16] KVM: x86/pmu: Add PMC bitmap accessor helpers Zide Chen
2026-08-27 22:37 ` Zide Chen [this message]
2026-08-27 22:37 ` [PATCH v2 07/16] KVM: x86/pmu: Expose kvm_host_pmu to vendor modules Zide Chen
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-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-08-27 22:37 ` [PATCH v2 12/16] KVM: x86/pmu: Populate CPUID.0AH:ECX fixed-counter bitmap Zide Chen
2026-08-27 22:37 ` [PATCH v2 13/16] KVM: x86/pmu: Factor out fixed counter control bit calculation Zide Chen
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-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
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=20260827223755.143247-7-zide.chen@intel.com \
--to=zide.chen@intel.com \
--cc=Manali.Shukla@amd.com \
--cc=Sandipan.Das@amd.com \
--cc=ak@linux.intel.com \
--cc=dapeng1.mi@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 \
/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.