git: 461da47e45e7 - main - iwm: mask closed_rb_num to the RX ring size
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 17 Oct 2026 21:38:08 UTC
The branch main has been updated by adrian:
URL: https://cgit.FreeBSD.org/src/commit/?id=461da47e45e7f8ef8754875f4820d3855e7f4097
commit 461da47e45e7f8ef8754875f4820d3855e7f4097
Author: Adrian Chadd <adrian@FreeBSD.org>
AuthorDate: 2026-10-17 21:32:51 +0000
Commit: Adrian Chadd <adrian@FreeBSD.org>
CommitDate: 2026-10-17 21:32:51 +0000
iwm: mask closed_rb_num to the RX ring size
iwm_notif_intr() reads hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff and
loops while (sc->rxq.cur != hw) without masking hw to the ring size (512 entries
for 9000-series MQ RX, 256 for legacy). If the hardware reports a value at or
above the ring size, cur never equals hw: the loop walks stale ring entries
indefinitely and the write-pointer update uses a bogus index. Linux iwlwifi
masks the value (5eae443eb5e2) and OpenBSD has done the same since 9000-series
support was added (3287dca4fa10).
This was found while debugging an iwm crash on another BSD using the same
driver lineage (DragonFly, upstream bug 3449)
Locally tested:
* 7260, 9260, STA mode
PR: kern/299427
Submitted by: David Bidner <david@crap.solutions>
Differential Revision: https://reviews.freebsd.org/D60824
---
sys/dev/iwm/if_iwm.c | 2 ++
sys/dev/iwm/if_iwmvar.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c
index 1bd07fa07102..dcf1e64ad6e1 100644
--- a/sys/dev/iwm/if_iwm.c
+++ b/sys/dev/iwm/if_iwm.c
@@ -6083,6 +6083,8 @@ iwm_notif_intr(struct iwm_softc *sc)
}
hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff;
+ /* Mask the returned value to the hardware ring size */
+ hw &= (count - 1);
/*
* Process responses
diff --git a/sys/dev/iwm/if_iwmvar.h b/sys/dev/iwm/if_iwmvar.h
index 4497bd91c8a1..92c70dee4eb9 100644
--- a/sys/dev/iwm/if_iwmvar.h
+++ b/sys/dev/iwm/if_iwmvar.h
@@ -293,6 +293,7 @@ struct iwm_tx_ring {
int cur;
};
+/* Note: these are used as a mask; must be a power of 2 */
#define IWM_RX_LEGACY_RING_COUNT 256
#define IWM_RX_MQ_RING_COUNT 512