Index: sys/dev/hwpmc/hwpmc_arm64.c =================================================================== --- sys/dev/hwpmc/hwpmc_arm64.c +++ sys/dev/hwpmc/hwpmc_arm64.c @@ -175,10 +175,14 @@ pac = arm64_pcpu[cpu]; - caps = a->pm_caps; - if (a->pm_class != PMC_CLASS_ARMV8) { + if (a->pm_class != PMC_CLASS_ARMV8) return (EINVAL); - } + + /* check requested capabilities */ + caps = a->pm_caps; + if ((caps & ARMV8_PMC_CAPS) != caps) + return (EPERM); + pe = a->pm_ev; /* Adjust the config value if needed. */ Index: sys/dev/hwpmc/hwpmc_armv7.c =================================================================== --- sys/dev/hwpmc/hwpmc_armv7.c +++ sys/dev/hwpmc/hwpmc_armv7.c @@ -150,11 +150,15 @@ pac = armv7_pcpu[cpu]; - caps = a->pm_caps; if (a->pm_class != PMC_CLASS_ARMV7) return (EINVAL); - pe = a->pm_ev; + /* check requested capabilities */ + caps = a->pm_caps; + if ((caps & ARMV7_PMC_CAPS) != caps) + return (EPERM); + + pe = a->pm_ev; config = (pe & EVENT_ID_MASK); pm->pm_md.pm_armv7.pm_armv7_evsel = config; Index: sys/dev/hwpmc/hwpmc_beri.c =================================================================== --- sys/dev/hwpmc/hwpmc_beri.c +++ sys/dev/hwpmc/hwpmc_beri.c @@ -188,7 +188,7 @@ beri_allocate_pmc(int cpu, int ri, struct pmc *pm, const struct pmc_op_pmcallocate *a) { - uint32_t config; + uint32_t config, caps; int i; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), @@ -199,6 +199,11 @@ if (a->pm_class != beri_pmc_spec.ps_cpuclass) return (EINVAL); + /* check requested capabilities */ + caps = a->pm_caps; + if ((caps & beri_pmc_spec.ps_capabilities) != caps) + return (EPERM); + for (i = 0; i < BERI_NCOUNTERS; i++) { if (beri_event_codes[i].pe_ev == a->pm_ev) { config = i; Index: sys/dev/hwpmc/hwpmc_core.c =================================================================== --- sys/dev/hwpmc/hwpmc_core.c +++ sys/dev/hwpmc/hwpmc_core.c @@ -236,12 +236,14 @@ if (ri < 0 || ri > core_iaf_npmc) return (EINVAL); - caps = a->pm_caps; - - if (a->pm_class != PMC_CLASS_IAF || - (caps & IAF_PMC_CAPS) != caps) + if (a->pm_class != PMC_CLASS_IAF) return (EINVAL); + /* check requested capabilities */ + caps = a->pm_caps; + if ((caps & IAF_PMC_CAPS) != caps) + return (EPERM); + iap = &a->pm_md.pm_iap; config = iap->pm_iap_config; ev = IAP_EVSEL_GET(config); Index: sys/dev/hwpmc/hwpmc_e500.c =================================================================== --- sys/dev/hwpmc/hwpmc_e500.c +++ sys/dev/hwpmc/hwpmc_e500.c @@ -379,7 +379,10 @@ if (a->pm_class != PMC_CLASS_E500) return (EINVAL); + /* check requested capabilities */ caps = a->pm_caps; + if ((caps & POWERPC_PMC_CAPS) != caps) + return (EPERM); pe = a->pm_ev; config = PMLCax_FCS | PMLCax_FCU | Index: sys/dev/hwpmc/hwpmc_mips.c =================================================================== --- sys/dev/hwpmc/hwpmc_mips.c +++ sys/dev/hwpmc/hwpmc_mips.c @@ -82,9 +82,13 @@ KASSERT(ri >= 0 && ri < mips_npmcs, ("[mips,%d] illegal row index %d", __LINE__, ri)); - caps = a->pm_caps; if (a->pm_class != mips_pmc_spec.ps_cpuclass) return (EINVAL); + + caps = a->pm_caps; + if ((caps & mips_pmc_spec.ps_capabilities) != caps) + return (EPERM); + pe = a->pm_ev; counter = MIPS_CTR_ALL; event = 0; Index: sys/dev/hwpmc/hwpmc_power8.c =================================================================== --- sys/dev/hwpmc/hwpmc_power8.c +++ sys/dev/hwpmc/hwpmc_power8.c @@ -170,6 +170,11 @@ if (a->pm_class != PMC_CLASS_POWER8) return (EINVAL); + /* check requested capabilities */ + caps = a->pm_caps; + if ((caps & POWERPC_PMC_CAPS) != caps) + return (EPERM); + /* * PMC5 and PMC6 are not programmable and always count instructions * completed and cycles, respectively. @@ -187,8 +192,6 @@ if (counter != 0 && counter != ri + 1) return (EINVAL); - caps = a->pm_caps; - if (caps & PMC_CAP_SYSTEM) config |= POWERPC_PMC_KERNEL_ENABLE; if (caps & PMC_CAP_USER) Index: sys/dev/hwpmc/hwpmc_powerpc.c =================================================================== --- sys/dev/hwpmc/hwpmc_powerpc.c +++ sys/dev/hwpmc/hwpmc_powerpc.c @@ -215,7 +215,10 @@ if (a->pm_class != ppc_class) return (EINVAL); + /* check requested capabilities */ caps = a->pm_caps; + if ((caps & POWERPC_PMC_CAPS) != caps) + return (EPERM); pe = a->pm_ev; Index: sys/dev/hwpmc/hwpmc_uncore.c =================================================================== --- sys/dev/hwpmc/hwpmc_uncore.c +++ sys/dev/hwpmc/hwpmc_uncore.c @@ -199,12 +199,14 @@ if (ri < 0 || ri > uncore_ucf_npmc) return (EINVAL); - caps = a->pm_caps; - - if (a->pm_class != PMC_CLASS_UCF || - (caps & UCF_PMC_CAPS) != caps) + if (a->pm_class != PMC_CLASS_UCF) return (EINVAL); + /* check requested capabilities */ + caps = a->pm_caps; + if ((caps & UCF_PMC_CAPS) != caps) + return (EPERM); + flags = UCF_EN; pm->pm_md.pm_ucf.pm_ucf_ctrl = (flags << (ri * 4));