From nobody Mon Sep 07 07:22:19 2026 X-Original-To: dev-commits-src-branches@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 4hddn82cPKz6rbTF for ; Mon, 07 Sep 2026 07:22:20 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hddn818JRz3rVR for ; Mon, 07 Sep 2026 07:22:20 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788765740; 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=D0GmkMkK6qO3Wj7B8LV0qbSiEEmd8LDpenMyWJlRxbY=; b=HDVRfPQ/hST/y5pd5uecIHtFjB0Kf7xJiw4/K2rW5LKz9Sp2AbPecXTONRUH9qHMpE0+i0 6Chqjo9e1HuoquNGTALE2Kg0SeMprzPfbKPoz5esiovY48lD9bvZ0IAOstf7lUlC2prPiU KWOcJOMo1052zcWQUczdopzCNz7pDSuSy2wq17B9o1ynZdnIbq3iecqJrM12TXmoR6VyZu AYF++WEapbWH3qUv6x9hlQWKoI8QOo1GO+JjdKlqa5qkxPGBP3u65a4Z7mW/mwprzcdNrR 3wGJjZC9D5+tSIyt5yQOrxEpEQibDNPcwzLBlsmtBp6fYKXgSgnAI+gba0hZ0A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1788765740; a=rsa-sha256; cv=none; b=jw+pyRWu9FNY0ZCrpoJBrSlciukbAfB6rcNfbJGvVRpmGhpI9Zt3wG+3mzv1ZyPAmX9a7b ADzGjNjnZsJjZ2JwsUUV+gc2JoiWawVFyTyhjF+YNn2t5v5d1BT8cboI8ha9orElDIKarA K978MPA2q7mOUBPJKdkrdzgMw0TIRvwjP75dcyEFdAsl5RfMIxp4ab0kvbpeJpKld+UdFg bl8kDtOjVN/EMGj2+5r9emUYLM35ch/YjxbKwnWOwfeTNrvhzISfB4zUTmR537+UGLylrN IYTKkEEsVHJ7Lx9twe4sN8b3OZJZKlrQ3Akk7YLx3Gs6K0eLlzjG7V8aQkPN3g== 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=1788765740; 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=D0GmkMkK6qO3Wj7B8LV0qbSiEEmd8LDpenMyWJlRxbY=; b=c4frkKyXU0FavLL85oEo/hQFQqJzKdMFNUOpxBolzinY3j7g0KPV6iLCSmf4+so0YOHT3Y x7cpyYJ97IIwwMsI8/BOgtnQ/YwquDSvPHj70nLzCNfYinoQCLhPEPldnon2CkIYrw+UlT PY//zyvhYM/NNBd95MM5dByAP7YL1abDN9O/GcFDtVyCSascmgEMjmr/cpOpuE3c9/F7vA 00eiYDCuzTLMfpJiwC1+5nridyB2wwuL3BePr8eipqsWPVtknvTGdMV85P89wHAkfQ5qbM ggMRcsodpZd6U04jc8TPWHkZJoynSfOK14caB5C6B3JReXuCMNlYlgSJG5a9Cg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hddn76x6yz178R for ; Mon, 07 Sep 2026 07:22:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 385f5 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 07 Sep 2026 07:22:19 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 8dcd6ea37646 - stable/15 - e1000: Serialize 82579 CSR writes with the Management Engine List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@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/stable/15 X-Git-Reftype: branch X-Git-Commit: 8dcd6ea3764645d336362e6f4d1eba667a00107c Auto-Submitted: auto-generated Date: Mon, 07 Sep 2026 07:22:19 +0000 Message-Id: <6a9e662b.385f5.30bd8b87@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=8dcd6ea3764645d336362e6f4d1eba667a00107c commit 8dcd6ea3764645d336362e6f4d1eba667a00107c Author: Kevin Bowling AuthorDate: 2026-08-16 07:10:09 +0000 Commit: Kevin Bowling CommitDate: 2026-09-07 07:22:03 +0000 e1000: Serialize 82579 CSR writes with the Management Engine The 82579 PCIm2PCI arbiter can acknowledge a host MAC CSR write while the Management Engine is accessing another CSR. The host write can be lost; subsequent target accesses may no longer be claimed by the MAC and can hang the system. For 82579 controllers with valid management firmware, wait for the ME CSR access indication before every MAC CSR write. Keep the wait bounded and use DELAY because writes occur in interrupt and datapath contexts. Verify every transmit and receive tail write. If a tail does not hold the requested value, disable its datapath direction and request a full iflib reset. Keep the ordinary register-write path as a direct MMIO write behind a predicted per-device gate. Contain the wait and tail recovery in the 82579 slow path rather than adding tail-specific accessors and state to the rest of the e1000 family. Documentation on the PCH NICs is scare so Intel's Linux e1000e fixes publicly document the hardware failure and required serialization as commits bdc125f73f3c and d601afcae2fe. This implementation is a bit cleaner. Tested on a Thinkpad T430 (82579LM) with a test kernel to simulate ME contention without incident as well as lost tail writes causing a succesful recovery. Sponsored by: BBOX.io (cherry picked from commit e7aa5a5a3f690f49488f89e01444ba1bcebc427b) --- sys/dev/e1000/e1000_osdep.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ sys/dev/e1000/e1000_osdep.h | 20 +++++++++------ sys/dev/e1000/if_em.c | 9 +++++++ 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/sys/dev/e1000/e1000_osdep.c b/sys/dev/e1000/e1000_osdep.c index 8b598f18cf12..c38e963f2ea3 100644 --- a/sys/dev/e1000/e1000_osdep.c +++ b/sys/dev/e1000/e1000_osdep.c @@ -36,6 +36,66 @@ int e1000_use_pause_delay = 0; +/* + * Wait while the 82579 Management Engine owns the PCIm2PCI arbiter. DELAY + * is required because CSR writes also occur from interrupt and datapath + * contexts where sleeping is forbidden. + */ +static void +e1000_pcim2pci_arbiter_wait(struct e1000_osdep *osdep) +{ + int i; + + i = E1000_ICH_FWSM_PCIM2PCI_COUNT; + while ((bus_space_read_4(osdep->mem_bus_space_tag, + osdep->mem_bus_space_handle, E1000_FWSM) & + E1000_ICH_FWSM_PCIM2PCI) != 0 && --i != 0) + DELAY(50); +} + +/* + * Serialize an 82579 MAC CSR write against the Management Engine. The + * FreeBSD driver exposes one queue on this controller, so recognize its two + * tail registers here and verify them without imposing tail-specific APIs on + * the rest of the e1000 family. + */ +void +e1000_pcim2pci_write(struct e1000_osdep *osdep, uint32_t reg, uint32_t value) +{ + uint32_t control, control_reg, enable; + const char *direction; + + e1000_pcim2pci_arbiter_wait(osdep); + bus_space_write_4(osdep->mem_bus_space_tag, + osdep->mem_bus_space_handle, reg, value); + + if (reg == E1000_TDT(0)) { + control_reg = E1000_TCTL; + enable = E1000_TCTL_EN; + direction = "transmit"; + } else if (reg == E1000_RDT(0)) { + control_reg = E1000_RCTL; + enable = E1000_RCTL_EN; + direction = "receive"; + } else { + return; + } + if (bus_space_read_4(osdep->mem_bus_space_tag, + osdep->mem_bus_space_handle, reg) == value) + return; + + control = bus_space_read_4(osdep->mem_bus_space_tag, + osdep->mem_bus_space_handle, control_reg); + e1000_pcim2pci_arbiter_wait(osdep); + bus_space_write_4(osdep->mem_bus_space_tag, + osdep->mem_bus_space_handle, control_reg, control & ~enable); + device_printf(osdep->dev, + "Management Engine caused an invalid %s tail write; " + "requesting reset\n", direction); + iflib_request_reset(osdep->ctx); + iflib_admin_intr_deferred(osdep->ctx); +} + static void e1000_enable_pause_delay(void *use_pause_delay) { diff --git a/sys/dev/e1000/e1000_osdep.h b/sys/dev/e1000/e1000_osdep.h index ba1c8a16fad1..bac71d34de45 100644 --- a/sys/dev/e1000/e1000_osdep.h +++ b/sys/dev/e1000/e1000_osdep.h @@ -161,8 +161,11 @@ struct e1000_osdep bus_space_handle_t flash_bus_space_handle; device_t dev; if_ctx_t ctx; + bool pcim2pci_arbiter_wa; }; +void e1000_pcim2pci_write(struct e1000_osdep *, uint32_t, uint32_t); + #define E1000_REGISTER(hw, reg) (((hw)->mac.type >= e1000_82543) \ ? reg : e1000_translate_register_82542(reg)) @@ -173,11 +176,6 @@ struct e1000_osdep bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, offset) -/* Write to an absolute offset in the adapter's memory space */ -#define E1000_WRITE_OFFSET(hw, offset, value) \ - bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \ - ((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, offset, value) - static __inline uint32_t e1000_rd32(struct e1000_osdep *osdep, uint32_t reg) { @@ -199,10 +197,18 @@ e1000_wr32(struct e1000_osdep *osdep, uint32_t reg, uint32_t value) ("e1000: register offset %#jx too large (max is %#jx)", (uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size)); - bus_space_write_4(osdep->mem_bus_space_tag, - osdep->mem_bus_space_handle, reg, value); + if (__predict_true(!osdep->pcim2pci_arbiter_wa)) { + bus_space_write_4(osdep->mem_bus_space_tag, + osdep->mem_bus_space_handle, reg, value); + return; + } + e1000_pcim2pci_write(osdep, reg, value); } +/* Write to an absolute offset in the adapter's memory space. */ +#define E1000_WRITE_OFFSET(hw, offset, value) \ + e1000_wr32((hw)->back, (offset), (value)) + /* Register READ/WRITE macros */ #define E1000_READ_REG(hw, reg) \ diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 6e215152c9e8..f524d4d47572 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1203,6 +1203,15 @@ em_if_attach_pre(if_ctx_t ctx) error = ENXIO; goto err_pci; } + /* + * 82579 can lose a host CSR write while the Management Engine owns + * the PCIm2PCI arbiter. Enable the OS register write interlock before + * shared code initialization performs any MAC writes. + */ + if (hw->mac.type == e1000_pch2lan && + (E1000_READ_REG(hw, E1000_FWSM) & + E1000_ICH_FWSM_FW_VALID) != 0) + sc->osdep.pcim2pci_arbiter_wa = true; /* ** For ICH8 and family we need to