Skip site navigation (1)Skip section navigation (2)
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>