aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorAli Mashtizadeh <mashti@uwaterloo.ca>2026-03-01 22:08:30 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2026-03-16 23:31:15 +0000
commit44a983d249d05d932b6cff333f130baf70febc22 (patch)
tree2d4f37205db9ad39f3bfd19c49e81c9d60480507 /sys/dev
parentf0e0c4c52971f58d41a89690d402520500d286bd (diff)
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/hwpmc/hwpmc_amd.c15
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c45
2 files changed, 60 insertions, 0 deletions
diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c
index c27d93995d59..51505bfcff37 100644
--- a/sys/dev/hwpmc/hwpmc_amd.c
+++ b/sys/dev/hwpmc/hwpmc_amd.c
@@ -703,6 +703,20 @@ amd_get_msr(int ri, uint32_t *msr)
}
/*
+ * Return the capabilities of the given PMC.
+ */
+static int
+amd_get_caps(int ri, uint32_t *caps)
+{
+ KASSERT(ri >= 0 && ri < amd_npmcs,
+ ("[amd,%d] ri %d out of range", __LINE__, ri));
+
+ *caps = amd_pmcdesc[ri].pm_descr.pd_caps;
+
+ return (0);
+}
+
+/*
* Processor-dependent initialization.
*/
static int
@@ -958,6 +972,7 @@ pmc_amd_initialize(void)
pcd->pcd_start_pmc = amd_start_pmc;
pcd->pcd_stop_pmc = amd_stop_pmc;
pcd->pcd_write_pmc = amd_write_pmc;
+ pcd->pcd_get_caps = amd_get_caps;
pmc_mdep->pmd_cputype = cputype;
pmc_mdep->pmd_intr = amd_intr;
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 1fa021429c5a..fb1fdf832398 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -4538,6 +4538,51 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
}
break;
+ /*
+ * Get the PMC capabilities
+ */
+
+ case PMC_OP_GETCAPS:
+ {
+ struct pmc_op_caps c;
+ struct pmc *pm;
+ struct pmc_classdep *pcd;
+ pmc_id_t pmcid;
+ int adjri, ri;
+
+ PMC_DOWNGRADE_SX();
+
+ if ((error = copyin(arg, &c, sizeof(c))) != 0)
+ break;
+
+ pmcid = c.pm_pmcid;
+
+ if ((error = pmc_find_pmc(pmcid, &pm)) != 0)
+ break;
+
+ KASSERT(pmcid == pm->pm_id,
+ ("[pmc,%d] pmc id %x != pmcid %x", __LINE__,
+ pm->pm_id, pmcid));
+
+ ri = PMC_TO_ROWINDEX(pm);
+ pcd = pmc_ri_to_classdep(md, ri, &adjri);
+
+ /*
+ * If PMC class has no GETCAPS return the class capabilities
+ * otherwise get the per counter capabilities.
+ */
+ if (pcd->pcd_get_caps == NULL) {
+ c.pm_caps = pcd->pcd_caps;
+ } else {
+ error = (*pcd->pcd_get_caps)(adjri, &c.pm_caps);
+ if (error < 0)
+ break;
+ }
+
+ if ((error = copyout(&c, arg, sizeof(c))) < 0)
+ break;
+ }
+ break;
default:
error = EINVAL;