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]> --- 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 185ea3631eee..e70628653e4b 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -690,6 +690,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 @@ -819,42 +836,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]; @@ -1089,7 +1070,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

