From nobody Mon Aug 3 10:19:26 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hDCMf6L4xz6n3fR for ; Mon, 03 Aug 2026 10:19:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hDCMf3sKyz3CyX for ; Mon, 03 Aug 2026 10:19:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785752366; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PFCKjHhWpR96Naw8vlwGOJm5K5sUWoqMRlAM/Hxbc/o=; b=FYvFnEP4T9ZUqOdyij+DgrR965SItaL7qHnnH23mSQDMoFxi0R2VqdZRqxqUgrIehox8i6 JVGpQlaxrGGaqDJC9r7vsiUjj5Ee+k0iewe3gVNc6eUHKWkrMBmmsxDRgFV73TCc5NY7vX 1Ha82TLWII+P0bu1IFqF2LDGkn/muM1k6Mz/gAWGU55q1mrR9lT3PGklA0oF3DuQLKE8go hgVK81uXogS2JEW4zYbq/ws6GhRxHZisZOqzj9Ghat3+3TP8K8oz0ghpfGjc0l40uov17l +0EiLTYtTURxCcjOtNDM9BFr18YcTsbtEeXKpk90EnTJSFDw/DBrNuuCXBzilg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785752366; a=rsa-sha256; cv=none; b=NaHgu0TSv9uDvVwf178f0plBOohTSAQ+vW/PHuzoAGVMOolbDo4BYXucocxQwNNzdvSFTR 8Sx97wGA8b2V1AQUpyjSMll8EdowjNumRyk6xzTNB1Uq5zdR17mpxuCpR4x/wWsgEa1Qv0 sgIrRCzs+mgSuHwkfvEn8OhpusEhEIh1Fq98B9RzqTih+/K9STo+rkw3x00uDGsx7GNEgw rkDaACV2N7LZp/ag949qDarywGx2StDKgJni2kdX7Ikb711qN5ubn2G3uVWbVw8sG00xE9 1WrV9jUboJFhfFQbQveoElm2v6ibmZC/3JdJ3MUE1NctjZXekGuan3TfDLQd5A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785752366; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PFCKjHhWpR96Naw8vlwGOJm5K5sUWoqMRlAM/Hxbc/o=; b=c2eZHn5ChEX7wT+45wBBhsKIHPPBbpuAbFQ0pIBa6lPJ1IY5feAHy2H0cnNgVI9Cvf7vzz SdpztyJq0QdyQ6ujWTXbD8YeC17nkcY2loIjk+EQGiyARK5k+u21ZNLuMsrG+IcYLe72Fw TliwZc66MgV/LVZOOOs6QmkqTnM7YiDPMEC8su545VM9ZNF/FW2LvSzOCQdAMYU1mNFd7Y 9cegqUJyvLUfVALwOPrEvbc1wlVEOFyfWihtvoz8Bj/YhNLe4O94YitEFIUPkfRmnfbK74 GwMSfEu9DrUHoNXgJ6tCaaYD7w+ZVqpe4Trq7OQ0OqYRHHvWLUx56bXuf4X2hg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hDCMf2hlzzwcm for ; Mon, 03 Aug 2026 10:19:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 42fad by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 03 Aug 2026 10:19:26 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: 176259efcb90 - main - igb: drain stale MDD state before interrupt arm List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 176259efcb907bd73079e4da83344077271916a5 Auto-Submitted: auto-generated Date: Mon, 03 Aug 2026 10:19:26 +0000 Message-Id: <6a706b2e.42fad.10bf6193@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=176259efcb907bd73079e4da83344077271916a5 commit 176259efcb907bd73079e4da83344077271916a5 Author: Kevin Bowling AuthorDate: 2026-08-03 05:38:11 +0000 Commit: Kevin Bowling CommitDate: 2026-08-03 10:18:42 +0000 igb: drain stale MDD state before interrupt arm IOV policy setup can leave MDDET and its read-clear diagnostic registers populated while the admin vector is masked. Carrying that state across the unmask can suppress the next spoof-event edge. Mark initialization for a one-shot drain and consume LVMMC, WVBR when applicable, and ICR immediately before EIMS/IMS arms the vector. Preserve the synthetic link-status cause across the arm-time ICR read, and clear the one-shot latch at reset preparation. --- sys/dev/e1000/if_em.c | 1 + sys/dev/e1000/if_em.h | 1 + sys/dev/e1000/if_igb_iov.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ sys/dev/e1000/if_igb_iov.h | 2 ++ 4 files changed, 54 insertions(+) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 5be866657e71..fb12345a3f43 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -4877,6 +4877,7 @@ igb_if_intr_enable(if_ctx_t ctx) E1000_WRITE_REG(hw, E1000_EIAC, reg | mask); reg = E1000_READ_REG(hw, E1000_EIAM); E1000_WRITE_REG(hw, E1000_EIAM, reg | mask); + igb_iov_intr_drain_stale(sc); E1000_WRITE_REG(hw, E1000_EIMS, mask); E1000_WRITE_REG(hw, E1000_IMS, E1000_IMS_LSC | igb_iov_intr_mask(sc)); diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h index a25aaff3307d..4204dee4d982 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -611,6 +611,7 @@ struct e1000_softc { u32 iov_pending; u32 iov_spoof_pending; u32 iov_blocked_pending; + u32 iov_intr_drain_pending; u32 iov_teardown; struct timeval iov_last_mdd_log; u16 num_vfs; diff --git a/sys/dev/e1000/if_igb_iov.c b/sys/dev/e1000/if_igb_iov.c index 5544d1e3dd8c..7a7348ede657 100644 --- a/sys/dev/e1000/if_igb_iov.c +++ b/sys/dev/e1000/if_igb_iov.c @@ -534,6 +534,33 @@ igb_iov_intr_mask(const struct e1000_softc *sc) return (E1000_IMS_VMMB | E1000_IMS_MDDET); } +void +igb_iov_intr_drain_stale(struct e1000_softc *sc) +{ + struct e1000_hw *hw; + u32 icr; + + if (atomic_readandclear_32(&sc->iov_intr_drain_pending) == 0) + return; + hw = &sc->hw; + /* + * Consume setup-time diagnostic state at the actual transition from + * masked to armed. Read ICR last so an event arriving after the drain + * remains pending and is delivered when the caller enables MDDET. + */ + (void)E1000_READ_REG(hw, E1000_LVMMC); + if (hw->mac.type == e1000_82576) + (void)E1000_READ_REG(hw, E1000_WVBR); + icr = E1000_READ_REG(hw, E1000_ICR); + /* + * em_if_init() injects LSC after IOV setup to close the post-reset + * link race. Preserve that cause across this MDDET-specific drain. + */ + if (__predict_true(icr != 0xffffffff) && + (icr & E1000_ICR_LSC) != 0) + E1000_WRITE_REG(hw, E1000_ICS, E1000_ICS_LSC); +} + static void igb_iov_vfta_shadow_invalidate(struct e1000_softc *sc) { @@ -650,6 +677,7 @@ igb_iov_reset_prepare(struct e1000_softc *sc) atomic_readandclear_32(&sc->iov_pending); atomic_readandclear_32(&sc->iov_spoof_pending); atomic_readandclear_32(&sc->iov_blocked_pending); + atomic_readandclear_32(&sc->iov_intr_drain_pending); } void @@ -1889,6 +1917,27 @@ igb_iov_initialize(struct e1000_softc *sc) E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_PFRSTD); E1000_WRITE_FLUSH(hw); + /* + * MDDET remains masked until iov_hw_active is published and iflib + * rearms the admin vector. Programming the per-pool policy above can + * leave a setup-time MDDET observation in the read-clear registers. + * If that stale cause is carried across the unmask, a later ordinary + * spoof can update LVMMC without generating a new interrupt edge. + * + * Drain only after all IOV policy is installed and before exposing the + * active state. Mailbox requests are also serviced by the periodic + * admin pass, and ping_all_vfs() below supplies a fresh notification. + */ + (void)E1000_READ_REG(hw, E1000_LVMMC); + if (hw->mac.type == e1000_82576) + (void)E1000_READ_REG(hw, E1000_WVBR); + /* Read ICR last so a later event remains pending for the arm below. */ + (void)E1000_READ_REG(hw, E1000_ICR); + atomic_readandclear_32(&sc->iov_mdd_cause); + atomic_readandclear_32(&sc->iov_pending); + atomic_readandclear_32(&sc->iov_spoof_pending); + atomic_readandclear_32(&sc->iov_blocked_pending); + atomic_store_rel_32(&sc->iov_intr_drain_pending, 1); sc->iov_hw_active = true; igb_iov_ping_all_vfs(sc); } @@ -2027,6 +2076,7 @@ igb_if_iov_uninit(if_ctx_t ctx) atomic_readandclear_32(&sc->iov_pending); atomic_readandclear_32(&sc->iov_spoof_pending); atomic_readandclear_32(&sc->iov_blocked_pending); + atomic_readandclear_32(&sc->iov_intr_drain_pending); atomic_store_rel_32(&sc->iov_teardown, 0); } diff --git a/sys/dev/e1000/if_igb_iov.h b/sys/dev/e1000/if_igb_iov.h index f24b3199867e..8bd576d47649 100644 --- a/sys/dev/e1000/if_igb_iov.h +++ b/sys/dev/e1000/if_igb_iov.h @@ -31,6 +31,7 @@ void igb_iov_mdd_event(struct e1000_softc *); void igb_iov_ping_all_vfs(struct e1000_softc *); void igb_iov_reset_prepare(struct e1000_softc *); u32 igb_iov_intr_mask(const struct e1000_softc *); +void igb_iov_intr_drain_stale(struct e1000_softc *); void igb_iov_rebuild_mta(struct e1000_softc *); void igb_iov_rebuild_vlan(struct e1000_softc *); void igb_iov_update_pf_vmolr(struct e1000_softc *); @@ -48,6 +49,7 @@ void igb_iov_update_pf_vmolr(struct e1000_softc *); #define igb_iov_ping_all_vfs(_sc) #define igb_iov_reset_prepare(_sc) #define igb_iov_intr_mask(_sc) (0) +#define igb_iov_intr_drain_stale(_sc) ((void)(_sc)) #define igb_iov_rebuild_mta(_sc) #define igb_iov_rebuild_vlan(_sc) #define igb_iov_update_pf_vmolr(_sc)