Date: Thu, 12 Mar 2026 15:29:09 +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: Paulo Fragoso <paulo@nlink.com.br> Subject: git: ce9aff829e02 - main - hwpmc_amd: fix amd_get_msr() MSR offset for newer counter bases Message-ID: <69b2dbc5.3cf06.4ef36fc5@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=ce9aff829e02c9a21c04eae77a45f2193d1ed5a1 commit ce9aff829e02c9a21c04eae77a45f2193d1ed5a1 Author: Paulo Fragoso <paulo@nlink.com.br> AuthorDate: 2026-03-12 15:21:33 +0000 Commit: Mitchell Horne <mhorne@FreeBSD.org> CommitDate: 2026-03-12 15:29:04 +0000 hwpmc_amd: fix amd_get_msr() MSR offset for newer counter bases The previous code subtracted AMD_PMC_PERFCTR_0 (0xC0010004) from all perfctr MSR addresses to compute a relative offset. This is incorrect for counters using AMD_PMC_CORE_BASE (0xC0010200), AMD_PMC_L3_BASE (0xC0010230), and AMD_PMC_DF_BASE (0xC0010240), producing wrong offsets. Fix by promoting amd_core_npmcs, amd_l3_npmcs, and amd_df_npmcs to static module-level variables and computing the correct flat RDPMC index per AMD BKDG 24594 page 440: ECX 0-5: Core counters 0-5 ECX 6-9: DF counters 0-3 ECX 10-15: L3 Cache counters 0-5 ECX 16-27: DF counters 4-15 ECX > 27: Reserved, returns EINVAL Reviewed by: Ali Mashtizadeh <ali@mashtizadeh.com>, mhorne Sponsored by: NLINK (https://nlink.com.br), Recife, Brazil Fixes: 37bba2ad92d8 ("hwpmc_amd: Add support for additional counters") Differential Revision: https://reviews.freebsd.org/D55607 --- sys/dev/hwpmc/hwpmc_amd.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c index cf44f9362a72..c27d93995d59 100644 --- a/sys/dev/hwpmc/hwpmc_amd.c +++ b/sys/dev/hwpmc/hwpmc_amd.c @@ -60,8 +60,8 @@ struct amd_descr { }; static int amd_npmcs; +static int amd_core_npmcs, amd_l3_npmcs, amd_df_npmcs; static struct amd_descr amd_pmcdesc[AMD_NPMCS_MAX]; - struct amd_event_code_map { enum pmc_event pe_ev; /* enum value */ uint16_t pe_code; /* encoded event mask */ @@ -664,10 +664,41 @@ amd_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc) static int amd_get_msr(int ri, uint32_t *msr) { + int df_idx; + KASSERT(ri >= 0 && ri < amd_npmcs, ("[amd,%d] ri %d out of range", __LINE__, ri)); - *msr = amd_pmcdesc[ri].pm_perfctr - AMD_PMC_PERFCTR_0; + /* + * Map counter row index to RDPMC ECX value. + * + * AMD BKDG 24594 rev 3.37, page 440, + * "RDPMC Read Performance-Monitoring Counter": + * ECX 0-5: Core counters 0-5 + * ECX 6-9: DF/Northbridge counters 0-3 + * ECX 10-15: L3 Cache counters 0-5 + * ECX 16-27: DF/Northbridge counters 4-15 + * + * AMD PPR 57930-A0 section 2.1.9, + * "Register Sharing" for DF counter details. + */ + if (ri < amd_core_npmcs) { + /* ECX 0-5: Core counters */ + *msr = ri; + } else if (ri < amd_core_npmcs + amd_l3_npmcs) { + /* ECX 10-15: L3 Cache counters */ + *msr = 10 + (ri - amd_core_npmcs); + } else { + /* ECX 6-9: DF counters 0-3 + * ECX 16-27: DF counters 4-15 */ + df_idx = ri - amd_core_npmcs - amd_l3_npmcs; + if (df_idx < 4) + *msr = 6 + df_idx; + else if (df_idx < 16) + *msr = 16 + (df_idx - 4); + else + return (EINVAL); + } return (0); } @@ -767,7 +798,6 @@ pmc_amd_initialize(void) enum pmc_cputype cputype; int error, i, ncpus, nclasses; int family, model, stepping; - int amd_core_npmcs, amd_l3_npmcs, amd_df_npmcs; struct amd_descr *d; /*home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69b2dbc5.3cf06.4ef36fc5>
