git: 7a1aaca06c33 - main - hwpmc: Fix bug when stopping ibs-op

From: Mitchell Horne <mhorne_at_FreeBSD.org>
Date: Thu, 09 Apr 2026 16:35:29 UTC
The branch main has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=7a1aaca06c3384f90202dafa60440081d67d00fd

commit 7a1aaca06c3384f90202dafa60440081d67d00fd
Author:     Ali Mashtizadeh <ali@mashtizadeh.com>
AuthorDate: 2026-04-04 21:30:03 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2026-04-09 16:35:26 +0000

    hwpmc: Fix bug when stopping ibs-op
    
    In ibs_stop_pmc I accidently cleared the fetch max count value rather
    than the op max count value, when stopping the op counter.  This
    mitigates a bug in early pre-zen processors, but breaks using both
    counters simultaneously.  I also found that the max op count mask needs
    to be extended for recent zen processors.
    
    Reported by:    Andre Fernando da Silva
    Reviewed by:    mhorne
    Sponsored by:   Netflix
    Fixes:  e51ef8ae490f ("hwpmc: Initial support for AMD IBS")
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/2120
---
 sys/dev/hwpmc/hwpmc_ibs.c | 4 ++--
 sys/dev/hwpmc/hwpmc_ibs.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/dev/hwpmc/hwpmc_ibs.c b/sys/dev/hwpmc/hwpmc_ibs.c
index bfc135f06884..ec1afcb47666 100644
--- a/sys/dev/hwpmc/hwpmc_ibs.c
+++ b/sys/dev/hwpmc/hwpmc_ibs.c
@@ -270,7 +270,7 @@ ibs_stop_pmc(int cpu __diagused, int ri, struct pmc *pm)
 	 * Turn off the ENABLE bit, but unfortunately there are a few quirks
 	 * that generate excess NMIs.  Workaround #420 in the Revision Guide
 	 * for AMD Family 10h Processors 41322 Rev. 3.92 March 2012. requires
-	 * that we clear the count before clearing enable.
+	 * that we clear the max count before clearing enable.
 	 *
 	 * Even after clearing the counter spurious NMIs are still possible so
 	 * we use a per-CPU atomic variable to notify the interrupt handler we
@@ -290,7 +290,7 @@ ibs_stop_pmc(int cpu __diagused, int ri, struct pmc *pm)
 		wrmsr(IBS_FETCH_CTL, config);
 		break;
 	case IBS_PMC_OP:
-		wrmsr(IBS_FETCH_CTL, config & ~IBS_FETCH_CTL_MAXCNTMASK);
+		wrmsr(IBS_OP_CTL, config & ~IBS_OP_CTL_MAXCNTMASK);
 		DELAY(1);
 		config &= ~IBS_OP_CTL_ENABLE;
 		wrmsr(IBS_OP_CTL, config);
diff --git a/sys/dev/hwpmc/hwpmc_ibs.h b/sys/dev/hwpmc/hwpmc_ibs.h
index c66d54672543..1616a746ffef 100644
--- a/sys/dev/hwpmc/hwpmc_ibs.h
+++ b/sys/dev/hwpmc/hwpmc_ibs.h
@@ -112,7 +112,7 @@
 #define IBS_OP_CTL_VALID		(1ULL << 18) /* Valid */
 #define IBS_OP_CTL_ENABLE		(1ULL << 17) /* Enable */
 #define IBS_OP_CTL_L3MISSONLY		(1ULL << 16) /* L3 Miss Filtering */
-#define IBS_OP_CTL_MAXCNTMASK		0x0000FFFFULL
+#define IBS_OP_CTL_MAXCNTMASK		0x07F0FFFFULL
 
 #define IBS_OP_CTL_LDLAT_TO_CTL(_c)	((((ldlat) >> 7) - 1) << 59)
 #define IBS_OP_INTERVAL_TO_CTL(_c)	((((_c) >> 4) & 0x0000FFFFULL) | ((_c) & 0x07F00000))