On Mon, 20 Jul 2026 at 06:39, Akihiko Odaki <[email protected]> wrote: > > kvm_pmu_probe_armpmu() currently samples the current CPU internally, > which ties the helper to default PMU selection. > > Move that policy to kvm_arm_set_default_pmu() by passing > raw_smp_processor_id() from the caller, and make the helper search for > the pPMU covering an explicit CPU. Move the helper above > kvm_pmu_create_perf_event() so later code can reuse it when creating > PMU events for a VCPU's current pCPU. > > This preserves the existing default PMU selection behavior while > preparing fixed-counters-only mode to select a pPMU at runtime. > > Signed-off-by: Akihiko Odaki <[email protected]>
Reviewed-by: Fuad Tabba <[email protected]> Cheers, /fuad > --- > arch/arm64/kvm/pmu-emul.c | 72 > +++++++++++++++++++++++------------------------ > 1 file changed, 35 insertions(+), 37 deletions(-) > > diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c > index 27db8877f96e..78611eaecca2 100644 > --- a/arch/arm64/kvm/pmu-emul.c > +++ b/arch/arm64/kvm/pmu-emul.c > @@ -682,6 +682,23 @@ static int kvm_map_pmu_event(struct arm_pmu *pmu, > unsigned int eventsel) > return eventsel; > } > > +static struct arm_pmu *kvm_pmu_probe_armpmu(int cpu) > +{ > + struct arm_pmu_entry *entry; > + struct arm_pmu *pmu; > + > + guard(rcu)(); > + > + list_for_each_entry_rcu(entry, &arm_pmus, entry) { > + pmu = entry->arm_pmu; > + > + if (cpumask_test_cpu(cpu, &pmu->supported_cpus)) > + return pmu; > + } > + > + return NULL; > +} > + > /** > * kvm_pmu_create_perf_event - create a perf event for a counter > * @pmc: Counter context > @@ -811,42 +828,6 @@ void kvm_host_pmu_init(struct arm_pmu *pmu) > list_add_tail_rcu(&entry->entry, &arm_pmus); > } > > -static struct arm_pmu *kvm_pmu_probe_armpmu(void) > -{ > - struct arm_pmu_entry *entry; > - struct arm_pmu *pmu; > - int cpu; > - > - guard(rcu)(); > - > - /* > - * It is safe to use a stale cpu to iterate the list of PMUs so long > as > - * the same value is used for the entirety of the loop. Given this, > and > - * the fact that no percpu data is used for the lookup there is no > need > - * to disable preemption. > - * > - * It is still necessary to get a valid cpu, though, to probe for the > - * default PMU instance as userspace is not required to specify a PMU > - * type. In order to uphold the preexisting behavior KVM selects the > - * PMU instance for the core during vcpu init. A dependent use > - * case would be a user with disdain of all things big.LITTLE that > - * affines the VMM to a particular cluster of cores. > - * > - * In any case, userspace should just do the sane thing and use the > UAPI > - * to select a PMU type directly. But, be wary of the baggage being > - * carried here. > - */ > - cpu = raw_smp_processor_id(); > - list_for_each_entry_rcu(entry, &arm_pmus, entry) { > - pmu = entry->arm_pmu; > - > - if (cpumask_test_cpu(cpu, &pmu->supported_cpus)) > - return pmu; > - } > - > - return NULL; > -} > - > static u64 __compute_pmceid(struct arm_pmu *pmu, bool pmceid1) > { > u32 hi[2], lo[2]; > @@ -1072,7 +1053,24 @@ static void kvm_arm_set_pmu(struct kvm *kvm, struct > arm_pmu *arm_pmu) > */ > int kvm_arm_set_default_pmu(struct kvm *kvm) > { > - struct arm_pmu *arm_pmu = kvm_pmu_probe_armpmu(); > + /* > + * It is safe to use a stale cpu to iterate the list of PMUs so long > as > + * the same value is used for the entirety of the loop. Given this, > and > + * the fact that no percpu data is used for the lookup there is no > need > + * to disable preemption. > + * > + * It is still necessary to get a valid cpu, though, to probe for the > + * default PMU instance as userspace is not required to specify a PMU > + * type. In order to uphold the preexisting behavior KVM selects the > + * PMU instance for the core during vcpu init. A dependent use > + * case would be a user with disdain of all things big.LITTLE that > + * affines the VMM to a particular cluster of cores. > + * > + * In any case, userspace should just do the sane thing and use the > UAPI > + * to select a PMU type directly. But, be wary of the baggage being > + * carried here. > + */ > + struct arm_pmu *arm_pmu = > kvm_pmu_probe_armpmu(raw_smp_processor_id()); > > if (!arm_pmu) > return -ENODEV; > > -- > 2.55.0 > >

