diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c --- a/lib/libpmc/libpmc.c +++ b/lib/libpmc/libpmc.c @@ -33,7 +33,6 @@ #include #include -#include #include #include #include @@ -1083,14 +1082,8 @@ r = spec_copy = strdup(ctrspec); ctrname = strsep(&r, ","); if (pmc_pmu_enabled()) { - if (pmc_pmu_pmcallocate(ctrname, &pmc_config) == 0) { - /* - * XXX: pmclog_get_event exploits this to disambiguate - * PMU from PMC event codes in PMCALLOCATE events. - */ - assert(pmc_config.pm_ev < PMC_EVENT_FIRST); + if (pmc_pmu_pmcallocate(ctrname, &pmc_config) == 0) goto found; - } } free(spec_copy); spec_copy = NULL; diff --git a/lib/libpmc/libpmc_pmu_util.c b/lib/libpmc/libpmc_pmu_util.c --- a/lib/libpmc/libpmc_pmu_util.c +++ b/lib/libpmc/libpmc_pmu_util.c @@ -649,7 +649,6 @@ assert(idx >= 0); pm->pm_ev = idx; pm->pm_md.pm_md_config = ped.ped_event; - pm->pm_md.pm_md_flags |= PM_MD_RAW_EVENT; pm->pm_class = PMC_CLASS_ARMV8; pm->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE); @@ -680,5 +679,6 @@ return (error); } + pm->pm_flags |= PMC_F_EV_PMU; return (0); } diff --git a/lib/libpmc/pmclog.c b/lib/libpmc/pmclog.c --- a/lib/libpmc/pmclog.c +++ b/lib/libpmc/pmclog.c @@ -357,15 +357,10 @@ PMCLOG_READ64(le,ev->pl_u.pl_a.pl_rate); /* - * Could be either a PMC event code or a PMU event index; - * assume that their encodings don't overlap (i.e. no PMU event - * table is more than 0x1000 entries) to distinguish them here. - * Otherwise pmc_pmu_event_get_by_idx will go out of bounds if - * given a PMC event code when it knows about that CPU. - * - * XXX: Ideally we'd have user flags to give us that context. + * pl_event could contain either a PMC event code or a PMU + * event index. */ - if (ev->pl_u.pl_a.pl_event < PMC_EVENT_FIRST) + if ((ev->pl_u.pl_a.pl_flags & PMC_F_EV_PMU) != 0) ev->pl_u.pl_a.pl_evname = pmc_pmu_event_get_by_idx(ps->ps_cpuid, ev->pl_u.pl_a.pl_event); diff --git a/sys/arm64/include/pmc_mdep.h b/sys/arm64/include/pmc_mdep.h --- a/sys/arm64/include/pmc_mdep.h +++ b/sys/arm64/include/pmc_mdep.h @@ -45,8 +45,6 @@ union pmc_md_op_pmcallocate { struct { uint32_t pm_md_config; - uint32_t pm_md_flags; -#define PM_MD_RAW_EVENT 0x1 }; struct pmc_md_cmn600_pmu_op_pmcallocate pm_cmn600; struct pmc_md_dmc620_pmu_op_pmcallocate pm_dmc620; diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c --- a/sys/dev/hwpmc/hwpmc_amd.c +++ b/sys/dev/hwpmc/hwpmc_amd.c @@ -582,6 +582,9 @@ if (pd->pd_class != a->pm_class) return EINVAL; + if ((a->pm_flags & PMC_F_EV_PMU) == 0) + return (EINVAL); + caps = pm->pm_caps; PMCDBG2(MDP,ALL,1,"amd-allocate ri=%d caps=0x%x", ri, caps); diff --git a/sys/dev/hwpmc/hwpmc_arm64.c b/sys/dev/hwpmc/hwpmc_arm64.c --- a/sys/dev/hwpmc/hwpmc_arm64.c +++ b/sys/dev/hwpmc/hwpmc_arm64.c @@ -177,9 +177,9 @@ } pe = a->pm_ev; - /* Adjust the config value if needed. */ - config = a->pm_md.pm_md_config; - if ((a->pm_md.pm_md_flags & PM_MD_RAW_EVENT) == 0) { + if ((a->pm_flags & PMC_F_EV_PMU) != 0) { + config = a->pm_md.pm_md_config; + } else { config = (uint32_t)pe - PMC_EV_ARMV8_FIRST; if (config > (PMC_EV_ARMV8_LAST - PMC_EV_ARMV8_FIRST)) return (EINVAL); diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -239,6 +239,9 @@ if (a->pm_class != PMC_CLASS_IAF) return (EINVAL); + if ((a->pm_flags & PMC_F_EV_PMU) == 0) + return (EINVAL); + iap = &a->pm_md.pm_iap; config = iap->pm_iap_config; ev = IAP_EVSEL_GET(config); @@ -721,6 +724,9 @@ if (a->pm_class != PMC_CLASS_IAP) return (EINVAL); + if ((a->pm_flags & PMC_F_EV_PMU) == 0) + return (EINVAL); + iap = &a->pm_md.pm_iap; ev = IAP_EVSEL_GET(iap->pm_iap_config); diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -3349,7 +3349,8 @@ * Look for valid values for 'pm_flags'. */ if ((flags & ~(PMC_F_DESCENDANTS | PMC_F_LOG_PROCCSW | - PMC_F_LOG_PROCEXIT | PMC_F_CALLCHAIN | PMC_F_USERCALLCHAIN)) != 0) + PMC_F_LOG_PROCEXIT | PMC_F_CALLCHAIN | PMC_F_USERCALLCHAIN | + PMC_F_EV_PMU)) != 0) return (EINVAL); /* PMC_F_USERCALLCHAIN is only valid with PMC_F_CALLCHAIN. */ diff --git a/sys/dev/hwpmc/hwpmc_power8.c b/sys/dev/hwpmc/hwpmc_power8.c --- a/sys/dev/hwpmc/hwpmc_power8.c +++ b/sys/dev/hwpmc/hwpmc_power8.c @@ -168,6 +168,9 @@ if (a->pm_class != PMC_CLASS_POWER8) return (EINVAL); + if ((a->pm_flags & PMC_F_EV_PMU) == 0) + return (EINVAL); + /* * PMC5 and PMC6 are not programmable and always count instructions * completed and cycles, respectively. diff --git a/sys/dev/hwpmc/hwpmc_uncore.c b/sys/dev/hwpmc/hwpmc_uncore.c --- a/sys/dev/hwpmc/hwpmc_uncore.c +++ b/sys/dev/hwpmc/hwpmc_uncore.c @@ -199,6 +199,9 @@ if (a->pm_class != PMC_CLASS_UCF) return (EINVAL); + if ((a->pm_flags & PMC_F_EV_PMU) == 0) + return (EINVAL); + flags = UCF_EN; pm->pm_md.pm_ucf.pm_ucf_ctrl = (flags << (ri * 4)); @@ -498,6 +501,9 @@ if (a->pm_class != PMC_CLASS_UCP) return (EINVAL); + if ((a->pm_flags & PMC_F_EV_PMU) == 0) + return (EINVAL); + ucp = &a->pm_md.pm_ucp; ev = UCP_EVSEL(ucp->pm_ucp_config); switch (uncore_cputype) { diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -369,6 +369,14 @@ #define PMC_F_CALLCHAIN 0x00000080 /*OP ALLOCATE capture callchains */ #define PMC_F_USERCALLCHAIN 0x00000100 /*OP ALLOCATE use userspace stack */ +/* V10 API */ +#define PMC_F_EV_PMU 0x00000200 /* + * OP ALLOCATE: pm_ev has special + * userspace meaning; counter + * configuration is communicated + * through class-dependent fields + */ + /* internal flags */ #define PMC_F_ATTACHED_TO_OWNER 0x00010000 /*attached to owner*/ #define PMC_F_NEEDS_LOGFILE 0x00020000 /*needs log file */