static struct arm_pmu *kvm_pmu_probe_armpmu(void)
 {
-       struct perf_event_attr attr = { };
-       struct perf_event *event;
-       struct arm_pmu *pmu = NULL;
-
-       /*
-        * Create a dummy event that only counts user cycles. As we'll never
-        * leave this function with the event being live, it will never
-        * count anything. But it allows us to probe some of the PMU
-        * details. Yes, this is terrible.
-        */
-       attr.type = PERF_TYPE_RAW;
-       attr.size = sizeof(attr);
-       attr.pinned = 1;
-       attr.disabled = 0;
-       attr.exclude_user = 0;
-       attr.exclude_kernel = 1;
-       attr.exclude_hv = 1;
-       attr.exclude_host = 1;
-       attr.config = ARMV8_PMUV3_PERFCTR_CPU_CYCLES;
-       attr.sample_period = GENMASK(63, 0);
+       struct arm_pmu *tmp, *pmu = NULL;
+       struct arm_pmu_entry *entry;
+       int cpu;
 
-       event = perf_event_create_kernel_counter(&attr, -1, current,
-                                                kvm_pmu_perf_overflow, &attr);
+       mutex_lock(&arm_pmus_lock);
 
-       if (IS_ERR(event)) {
-               pr_err_once("kvm: pmu event creation failed %ld\n",
-                           PTR_ERR(event));
-               return NULL;
-       }
+       cpu = smp_processor_id();
+       list_for_each_entry(entry, &arm_pmus, entry) {
+               tmp = entry->arm_pmu;
 
-       if (event->pmu) {
-               pmu = to_arm_pmu(event->pmu);
-               if (pmu->pmuver == ID_AA64DFR0_EL1_PMUVer_NI ||
-                   pmu->pmuver == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
-                       pmu = NULL;
+               if (cpumask_test_cpu(cpu, &tmp->supported_cpus)) {
+                       pmu = tmp;
+                       break;
+               }
        }
 
-       perf_event_disable(event);
-       perf_event_release_kernel(event);
+       mutex_unlock(&arm_pmus_lock);
 
        return pmu;
 }