Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Jul 2026 17:15:58 +0000
From:      Mitchell Horne <mhorne@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Cc:        Andre Silva <andasilv@amd.com>
Subject:   git: 8c4d5701924f - main - hwpmc: Add EXTERROR diagnostics to the AMD and IBS allocators
Message-ID:  <6a5fa94e.375a1.2cb1a5f7@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=8c4d5701924f8401798265d2175f0b2bc704a222

commit 8c4d5701924f8401798265d2175f0b2bc704a222
Author:     Andre Silva <andasilv@amd.com>
AuthorDate: 2026-06-12 15:38:14 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2026-07-21 17:14:39 +0000

    hwpmc: Add EXTERROR diagnostics to the AMD and IBS allocators
    
    Replace bare EINVAL in AMD/IBS allocation and config-validation with
    EXTERROR(), so a failed pmc(3) allocation names the check and value.
    
    Register HWPMC_AMD in exterr_cat.h and the generated filenames.h.
    
    Signed-off-by:  Andre Silva <andasilv@amd.com>
    Reviewed by:    Ali Mashtizadeh <ali@mashtizadeh.com>, mhorne
    Sponsored by:   AMD
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/2180
---
 lib/libc/gen/exterr_cat_filenames.h |  1 +
 sys/dev/hwpmc/hwpmc_amd.c           | 24 ++++++++++++++------
 sys/dev/hwpmc/hwpmc_ibs.c           | 45 +++++++++++++++++++++++--------------
 sys/sys/exterr_cat.h                |  2 +-
 4 files changed, 47 insertions(+), 25 deletions(-)

diff --git a/lib/libc/gen/exterr_cat_filenames.h b/lib/libc/gen/exterr_cat_filenames.h
index 90e231879ccd..e098a94744f3 100644
--- a/lib/libc/gen/exterr_cat_filenames.h
+++ b/lib/libc/gen/exterr_cat_filenames.h
@@ -2,6 +2,7 @@
  * Automatically @generated, use
  * tools/build/make_libc_exterr_cat_filenames.sh
  */
+	[EXTERR_CAT_HWPMC_AMD] = "dev/hwpmc/hwpmc_amd.c",
 	[EXTERR_CAT_HWPMC_IBS] = "dev/hwpmc/hwpmc_ibs.c",
 	[EXTERR_CAT_VMM] = "dev/vmm/vmm_dev.c",
 	[EXTERR_CAT_FUSE_DEVICE] = "fs/fuse/fuse_device.c",
diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c
index b075837cd3e8..185ceff133b0 100644
--- a/sys/dev/hwpmc/hwpmc_amd.c
+++ b/sys/dev/hwpmc/hwpmc_amd.c
@@ -43,6 +43,9 @@
 #include <sys/sysctl.h>
 #include <sys/systm.h>
 
+#define	EXTERR_CATEGORY	EXTERR_CAT_HWPMC_AMD
+#include <sys/exterrvar.h>
+
 #include <machine/cpu.h>
 #include <machine/cpufunc.h>
 #include <machine/md_var.h>
@@ -405,21 +408,24 @@ amd_allocate_pmc(int cpu __unused, int ri, struct pmc *pm,
 
 	caps = pm->pm_caps;
 
-	if (((caps & PMC_CAP_PRECISE) != 0) &&
-	    ((pd->pd_caps & PMC_CAP_PRECISE) == 0))
-		return (EINVAL);
-
 	PMCDBG2(MDP, ALL, 1,"amd-allocate ri=%d caps=0x%x", ri, caps);
 
 	/* Validate sub-class. */
 	if (amd_pmcdesc[ri].pm_subclass != a->pm_md.pm_amd.pm_amd_sub_class)
 		return (EINVAL);
 
+	if (((caps & PMC_CAP_PRECISE) != 0) &&
+	    ((pd->pd_caps & PMC_CAP_PRECISE) == 0))
+		return (EINVAL);
+
 	if (strlen(pmc_cpuid) != 0) {
 		config = a->pm_md.pm_amd.pm_amd_config;
 		if ((config & ~amd_config_mask(amd_pmcdesc[ri].pm_subclass,
 		    caps)) != 0)
-			return (EINVAL);
+			return (EXTERROR(EINVAL,
+			    "AMD PMU config has unsupported bits %#jx",
+			    (uintmax_t)(config & ~amd_config_mask(
+			    amd_pmcdesc[ri].pm_subclass, caps))));
 		pm->pm_md.pm_amd.pm_amd_evsel = config;
 		PMCDBG2(MDP, ALL, 2, "amd-allocate ri=%d -> config=0x%jx",
 		    ri, (uintmax_t)config);
@@ -443,11 +449,15 @@ amd_allocate_pmc(int cpu __unused, int ri, struct pmc *pm,
 		}
 	}
 	if (i == amd_event_codes_size)
-		return (EINVAL);
+		return (EXTERROR(EINVAL,
+		    "AMD legacy event %ju is not supported",
+		    (uintmax_t)pe));
 
 	unitmask = a->pm_md.pm_amd.pm_amd_config & AMD_PMC_UNITMASK;
 	if ((unitmask & ~allowed_unitmask) != 0) /* disallow reserved bits */
-		return (EINVAL);
+		return (EXTERROR(EINVAL,
+		    "AMD unitmask %#jx exceeds allowed mask %#jx",
+		    (uintmax_t)unitmask, (uintmax_t)allowed_unitmask));
 
 	if (unitmask && (caps & PMC_CAP_QUALIFIER) != 0)
 		config |= unitmask;
diff --git a/sys/dev/hwpmc/hwpmc_ibs.c b/sys/dev/hwpmc/hwpmc_ibs.c
index 16bc5edd5019..ce9e038e5d0b 100644
--- a/sys/dev/hwpmc/hwpmc_ibs.c
+++ b/sys/dev/hwpmc/hwpmc_ibs.c
@@ -147,9 +147,14 @@ ibs_init_policy(void)
 static int
 ibs_validate_fetch_config(uint64_t config)
 {
+	uint64_t allowed_mask;
 
-	if ((config & ~(ibs_fetch_allowed_mask | ibs_fetch_extra_mask)) != 0)
-		return (EINVAL);
+	allowed_mask = ibs_fetch_allowed_mask | ibs_fetch_extra_mask;
+	if ((config & ~allowed_mask) != 0) {
+		return (EXTERROR(EINVAL,
+		    "IBS fetch ctl config 0x%jx has bits outside allowed mask"
+		    " 0x%jx", (uintmax_t)config, (uintmax_t)allowed_mask));
+	}
 
 	return (0);
 }
@@ -163,22 +168,27 @@ ibs_validate_op_config(uint64_t config)
 
 	if ((config & IBS_OP_CTL_LATFLTEN) != 0) {
 		if ((ibs_features & CPUID_IBSID_IBSLOADLATENCYFILT) == 0)
-			return (EINVAL);
+			return (EXTERROR(EINVAL,
+			    "IBS op load-latency filter is not supported"));
 		/*
 		 * Zen 6 decouples L3MISSONLY from load-latency filtering
 		 * (AMD pub 69205); enforce the pairing only on older parts.
 		 */
 		if ((ibs_features & CPUID_IBSID_IBSDIS) == 0 &&
 		    (config & IBS_OP_CTL_L3MISSONLY) == 0)
-			return (EINVAL);
+			return (EXTERROR(EINVAL,
+			    "IBS op load-latency filter requires l3miss"));
 
 		allowed_mask |= IBS_OP_CTL_LDLATMASK | IBS_OP_CTL_L3MISSONLY;
 	}
 
 	allowed_mask |= ibs_op_extra_mask;
 
-	if ((config & ~allowed_mask) != 0)
-		return (EINVAL);
+	if ((config & ~allowed_mask) != 0) {
+		return (EXTERROR(EINVAL,
+		    "IBS op ctl config 0x%jx has bits outside allowed mask"
+		    " 0x%jx", (uintmax_t)config, (uintmax_t)allowed_mask));
+	}
 
 	return (0);
 }
@@ -197,10 +207,11 @@ ibs_validate_fetch_ctl2_config(uint64_t config)
 
 	allowed_mask = ibs_fetch_ctl2_allowed_mask | ibs_fetch_ctl2_extra_mask;
 
-	if ((config & ~allowed_mask) != 0)
+	if ((config & ~allowed_mask) != 0) {
 		return (EXTERROR(EINVAL,
 		    "IBS fetch ctl2 config 0x%jx has bits outside allowed"
-		    " mask 0x%jx", (uint64_t)config, (uint64_t)allowed_mask));
+		    " mask 0x%jx", (uintmax_t)config, (uintmax_t)allowed_mask));
+	}
 
 	return (0);
 }
@@ -219,10 +230,11 @@ ibs_validate_op_ctl2_config(uint64_t config)
 
 	allowed_mask = ibs_op_ctl2_allowed_mask | ibs_op_ctl2_extra_mask;
 
-	if ((config & ~allowed_mask) != 0)
+	if ((config & ~allowed_mask) != 0) {
 		return (EXTERROR(EINVAL,
 		    "IBS op ctl2 config 0x%jx has bits outside allowed mask"
-		    " 0x%jx", (uint64_t)config, (uint64_t)allowed_mask));
+		    " 0x%jx", (uintmax_t)config, (uintmax_t)allowed_mask));
+	}
 
 	return (0);
 }
@@ -244,7 +256,8 @@ ibs_validate_pmc_config(int ri, uint64_t config, uint64_t config2)
 			return (error);
 		return (ibs_validate_op_ctl2_config(config2));
 	default:
-		return (EXTERROR(EINVAL, "invalid IBS PMC index %d", ri));
+		return (EXTERROR(EINVAL, "Unsupported IBS PMC type %ju",
+		    (uintmax_t)ri));
 	}
 }
 
@@ -364,13 +377,11 @@ ibs_allocate_pmc(int cpu __unused, int ri, struct pmc *pm,
 	KASSERT(ri >= 0 && ri < IBS_NPMCS,
 	    ("[ibs,%d] illegal row index %d", __LINE__, ri));
 
-	/* check class match */
+	/* Row discriminators; the allocation loop probes every row. */
 	if (a->pm_class != PMC_CLASS_IBS)
-		return (EXTERROR(EINVAL, "PMC class is not IBS"));
+		return (EINVAL);
 	if (a->pm_md.pm_ibs.ibs_type != ri)
-		return (EXTERROR(EINVAL,
-		    "IBS type %ju does not match PMC index %ju",
-		    (uint64_t)a->pm_md.pm_ibs.ibs_type, (uint64_t)ri));
+		return (EINVAL);
 
 	caps = pm->pm_caps;
 
@@ -390,7 +401,7 @@ ibs_allocate_pmc(int cpu __unused, int ri, struct pmc *pm,
 	}
 
 	if (!PMC_IS_SAMPLING_MODE(a->pm_mode))
-		return (EINVAL);
+		return (EXTERROR(EINVAL, "IBS only supports sampling mode"));
 
 	config = a->pm_md.pm_ibs.ibs_ctl;
 	config2 = a->pm_md.pm_ibs.ibs_ctl2;
diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h
index 1c3f894e8aff..e63d118d7eb7 100644
--- a/sys/sys/exterr_cat.h
+++ b/sys/sys/exterr_cat.h
@@ -42,6 +42,6 @@
 #define	EXTERR_CAT_VMM		17
 #define	EXTERR_CAT_HWPMC_IBS	18
 #define	EXTERR_CAT_LINKER	19
+#define	EXTERR_CAT_HWPMC_AMD	20
 
 #endif
-


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a5fa94e.375a1.2cb1a5f7>