git: 34b00ed041a4 - main - hwpmc: fix IBS fetch and op NMI handling
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 28 Sep 2026 17:43:35 UTC
The branch main has been updated by mhorne:
URL: https://cgit.FreeBSD.org/src/commit/?id=34b00ed041a49eecc85b9a91748145ada14d83c5
commit 34b00ed041a49eecc85b9a91748145ada14d83c5
Author: Andre Silva <andasilv@amd.com>
AuthorDate: 2026-09-28 17:39:56 +0000
Commit: Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2026-09-28 17:40:14 +0000
hwpmc: fix IBS fetch and op NMI handling
Service each IBS unit with a valid bit set when fetch and op share an
NMI. Otherwise, op samples can be lost. Treat the extra NMI that follows
as expected (skip it).
Reviewed by: mhorne
Fixes: e51ef8ae490f ("hwpmc: Initial support for AMD IBS")
Differential Revision: https://reviews.freebsd.org/D60004
---
sys/dev/hwpmc/hwpmc_ibs.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/sys/dev/hwpmc/hwpmc_ibs.c b/sys/dev/hwpmc/hwpmc_ibs.c
index 17c3495f6a79..9e4af386f8d8 100644
--- a/sys/dev/hwpmc/hwpmc_ibs.c
+++ b/sys/dev/hwpmc/hwpmc_ibs.c
@@ -97,6 +97,7 @@ SYSCTL_U64(_kern_hwpmc, OID_AUTO, ibs_op_ctl2_extra_mask, CTLFLAG_RDTUN,
struct ibs_cpu {
int pc_status;
+ int pc_nmi_credit; /* latched NMIs already serviced */
struct pmc_hw pc_ibspmcs[IBS_NPMCS];
};
static struct ibs_cpu **ibs_pcpu;
@@ -702,24 +703,40 @@ pmc_ibs_intr(struct trapframe *tf)
pac = ibs_pcpu[cpu];
+ /*
+ * Fetch and op share an NMI. Both valid bits may be set on entry,
+ * so service each valid source or the skipped unit can stay frozen
+ * with no NMI pending to re-arm it.
+ */
config = rdmsr(IBS_FETCH_CTL);
if ((config & IBS_FETCH_CTL_VALID) != 0) {
pm = pac->pc_ibspmcs[IBS_PMC_FETCH].phw_pmc;
- retval = 1;
+ retval++;
pmc_ibs_process_fetch(pm, tf, config);
}
config = rdmsr(IBS_OP_CTL);
- if ((retval == 0) && ((config & IBS_OP_CTL_VALID) != 0)) {
+ if ((config & IBS_OP_CTL_VALID) != 0) {
pm = pac->pc_ibspmcs[IBS_PMC_OP].phw_pmc;
- retval = 1;
+ retval++;
pmc_ibs_process_op(pm, tf, config);
}
+ /*
+ * When both units were serviced, the second unit's NMI may still be
+ * latched and will arrive with no valid bit set. Claim that one
+ * NMI so it is not reported as unknown.
+ */
+ if (retval == 0 && pac->pc_nmi_credit != 0)
+ retval = 1;
+ pac->pc_nmi_credit = (retval == 2);
+ if (retval > 1)
+ retval = 1;
+
if (retval == 0) {
// Lets check for a stray NMI when stopping
if (atomic_load_int(&pac->pc_status) == IBS_CPU_STOPPING) {