git: 9330b2f73c04 - main - if_bnxt: Fix HWRM mailbox/DMA teardown race on detach

From: Sumit Saxena <ssaxena_at_FreeBSD.org>
Date: Fri, 09 Oct 2026 10:12:42 UTC
The branch main has been updated by ssaxena:

URL: https://cgit.FreeBSD.org/src/commit/?id=9330b2f73c04f06e39da5cf2279682a607185601

commit 9330b2f73c04f06e39da5cf2279682a607185601
Author:     Sumit Saxena <sumit.saxena@broadcom.com>
AuthorDate: 2026-07-31 15:43:59 +0000
Commit:     Sumit Saxena <ssaxena@FreeBSD.org>
CommitDate: 2026-10-09 08:24:43 +0000

    if_bnxt: Fix HWRM mailbox/DMA teardown race on detach
    
    iflib's generic device-deregister path never drains the admin task
    before calling IFDI_DETACH, so bnxt_update_admin_status() (scheduled
    once/sec) could still run concurrently with bnxt_detach(), racing on
    softc->hwrm_lock and the shared HWRM request/response DMA buffer that
    bnxt_detach() destroys. That race could leave the firmware-side HWRM
    mailbox inconsistent, surfacing as "Timeout sending HWRM_VER_GET" on
    the next module load.
    
    Add a softc->detached guard: set it as the first statement in
    bnxt_detach(), and bail out of bnxt_update_admin_status() immediately
    when it's set.
    
    Reviewed by:    gallatin
    MFC after:      2 weeks
    Sponsored by:   Broadcom Inc.
    Differential Revision:  https://reviews.freebsd.org/D58607
---
 sys/dev/bnxt/bnxt_en/bnxt.h    | 3 +++
 sys/dev/bnxt/bnxt_en/if_bnxt.c | 8 ++++++++
 2 files changed, 11 insertions(+)

diff --git a/sys/dev/bnxt/bnxt_en/bnxt.h b/sys/dev/bnxt/bnxt_en/bnxt.h
index f0b9d114ad72..e50c4157ac0b 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt.h
+++ b/sys/dev/bnxt/bnxt_en/bnxt.h
@@ -1350,6 +1350,9 @@ struct bnxt_softc {
 	struct bnxt_nvram_info	*nvm_info;
 	bool wol;
 	bool is_dev_init;
+	/* Cross-thread flag; access only via atomic_load_acq_int()/
+	 * atomic_store_rel_int(), never as a plain bool. */
+	volatile int detached;
 	struct bnxt_hw_lro	hw_lro;
 	uint8_t wol_filter_id;
 	uint16_t		rx_coal_usecs;
diff --git a/sys/dev/bnxt/bnxt_en/if_bnxt.c b/sys/dev/bnxt/bnxt_en/if_bnxt.c
index f179250ebbe0..2ea1fc97fd92 100644
--- a/sys/dev/bnxt/bnxt_en/if_bnxt.c
+++ b/sys/dev/bnxt/bnxt_en/if_bnxt.c
@@ -3202,6 +3202,11 @@ bnxt_detach(if_ctx_t ctx)
 	struct bnxt_vlan_tag *tmp;
 	int i;
 
+	/* Set first: the admin task isn't drained before IFDI_DETACH and can
+	 * still fire concurrently, so it must see this immediately via
+	 * atomic_store_rel_int()/atomic_load_acq_int(). */
+	atomic_store_rel_int(&softc->detached, 1);
+
 	bnxt_mpc_irq_cleanup(softc);
 	bnxt_rdma_aux_device_uninit(softc);
 	cancel_delayed_work_sync(&softc->fw_reset_task);
@@ -4217,6 +4222,9 @@ bnxt_update_admin_status(if_ctx_t ctx)
 	if (!BNXT_PF(softc))
 		return;
 
+	if (atomic_load_acq_int(&softc->detached))
+		return;
+
 	bnxt_hwrm_port_qstats(softc);
 
 	if (BNXT_CHIP_P5_PLUS(softc) &&