From nobody Thu Sep 03 00:53:55 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 4hb1Lr25Bfz6qyNb for ; Thu, 03 Sep 2026 00:53:56 +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 4hb1Lr10hFz3DcX for ; Thu, 03 Sep 2026 00:53:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788396836; 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=nPwg8I665KrLNFTy+6d/mA/UeEjU948lzNJVaqbWXl4=; b=QdMuAQu9v54h6osEWBUCGHGY3Ls/Y4jB7HShahDdjJqw/+xei33ppxzrWd1g0SDzhEyYwC TIgoA0j/giBVS9bMMelVfADoSM2BrkKX+cc0VqdjXhT6QU+qJyg3AaK+rQK59YlmZDTJRL 2cSM6f7Z/TVprNO4ZhNRkEFfcmTHke9tAEETSuSzVQkNJ5EAVvpdi/+Ufjwn5XPUEJURjb ztPextjITIBfjatqIFYzVMUJpi/zrSnlMhPFvVLruHIA3MTfl1b95DKOnYZ4Z7pv0D9aCq QS41jTvVoH5R9sN5K25LNTHc4VQh+Ucy4dtNm09Zm4aqESmDL1/Va6dmrLztdQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1788396836; a=rsa-sha256; cv=none; b=Qj4mta9HilfrKKBsbZQIwdlBFWtO+xdC7Tlm5rja50PlM0uIb42LwGJDZn9K9EJmchAbmH rHUIauBvXggqtGBZObxDjmMxbO+DO4Zvs7a4CicsGpZRQxDcyQEIE66GUHmEyxGdAFqDj4 Rc96OYP9OCIuqU95hhg9CE6uDmlPqewlaNh2owNvRp8zI/gee5pIf/vT94Y+USigomPr1I nPs6gRgxYJgiR/bF4Tn6cPwMUPG1mmNp5X4tc9Rh6YfymH5MKcj64S8YVhhxI1gMA2RecU x4U36ue9EFwG/D9lKcHcxu9zIcQtdUbf/bOqEiPf9FHkg8siGUoLoIhKQ2PaFw== 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=1788396836; 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=nPwg8I665KrLNFTy+6d/mA/UeEjU948lzNJVaqbWXl4=; b=pEva1aW0Cf/Blqa6LZaQEdNIGNVMaWuWBlHqplXIl0ppy8EPy5SzinKWyEXlwf5/unlBBf mF3ybZepyVJYa0lIpIdMKsd8ZUja+GrfihWtIqNYAlYHGk0LAxUSjB60st9e8oMjLiSRDa qh1IUJ2aQ7plt1tV3BWZJ5Cl/3nORzSb7N8dmwNJ8LTiS+01Jmrz2Ynqj+wtMkRJ/O+gEL DeOzSe7XynibTvYcQ1ZN+Jg7MGUTxevLsg0fV0tuSBSE6Aj+DJPbD9tlUlMFAt+BTqz+Rg U0RhWFiMCbrqMyee/txWofnkncrEleUgQE2uDAGuz72bPSUindC16/wBrcFSXQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hb1Lq6Sgvz15x7 for ; Thu, 03 Sep 2026 00:53:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1c6ee by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 03 Sep 2026 00:53:55 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 17fb42865e0e - stable/15 - bhyve: Keep passthrough PCI power state virtual 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: 17fb42865e0e0739f0e77dfa64b38298ae687f1c Auto-Submitted: auto-generated Date: Thu, 03 Sep 2026 00:53:55 +0000 Message-Id: <6a98c523.1c6ee.344f7bb9@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=17fb42865e0e0739f0e77dfa64b38298ae687f1c commit 17fb42865e0e0739f0e77dfa64b38298ae687f1c Author: Kevin Bowling AuthorDate: 2026-08-17 17:09:23 +0000 Commit: Kevin Bowling CommitDate: 2026-09-03 00:53:46 +0000 bhyve: Keep passthrough PCI power state virtual The passthrough Command register is emulated, but PMCSR writes were sent directly to the physical function. A guest D3hot-to-D0 transition can perform an internal reset and clear physical Command while its emulated copy remains enabled. Cache the Power Management capability and keep the physical D-state host-owned. Emulate the guest D-state and advertise No_Soft_Reset so the guest is not promised a function reset by a virtual power cycle. Restore the assignment-time virtual state after a managed FLR. Reviewed by: markj Sponsored by: BBOX.io (cherry picked from commit 3b90096cf9bcaec70b717e9ff0a9e23d14b600b6) --- usr.sbin/bhyve/pci_passthru.c | 53 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c index a78ca06c9d83..24d96764964d 100644 --- a/usr.sbin/bhyve/pci_passthru.c +++ b/usr.sbin/bhyve/pci_passthru.c @@ -100,6 +100,11 @@ struct passthru_softc { struct { int capoff; } psc_msix; + struct { + int capoff; + uint16_t pmcsr; + uint16_t reset_pmcsr; + } psc_pm; struct { int capoff; uint16_t devctl; @@ -331,6 +336,8 @@ cfginitcaps(struct passthru_softc *sc) capptr += 4; msixcap_ptr += 4; } + } else if (cap == PCIY_PMG) { + sc->psc_pm.capoff = ptr; } else if (cap == PCIY_EXPRESS) { sc->psc_pcie.capoff = ptr; } @@ -338,6 +345,13 @@ cfginitcaps(struct passthru_softc *sc) 1); } } + if (sc->psc_pm.capoff != 0) { + sc->psc_pm.pmcsr = passthru_read_config(&sel, + sc->psc_pm.capoff + PCIR_POWER_STATUS, 2); + /* The physical function remains in its host-owned power state. */ + sc->psc_pm.pmcsr |= PCIM_PSTAT_NOSOFTRESET; + sc->psc_pm.reset_pmcsr = sc->psc_pm.pmcsr; + } if (sc->psc_pcie.capoff != 0) { sc->psc_pcie.devctl = passthru_read_config(&sel, sc->psc_pcie.capoff + PCIER_DEVICE_CTL, 2); @@ -1120,6 +1134,8 @@ msixcap_access(struct passthru_softc *sc, int coff) #define PASSTHRU_DEVCTL_NO_WRITE PCIEM_CTL_PHANTHOM_FUNCS #define PASSTHRU_DEVCTL2_VIRT (PCIEM_CTL2_COMP_TIMO_VAL | \ PCIEM_CTL2_COMP_TIMO_DISABLE) +#define PASSTHRU_PMCSR_VIRT (PCIM_PSTAT_DMASK | \ + PCIM_PSTAT_NOSOFTRESET) static uint32_t passthru_cfg_field_mask(int coff, int bytes, int fieldoff, uint16_t mask) @@ -1243,6 +1259,8 @@ passthru_reset_capability_state(struct passthru_softc *sc) (sc->psc_pcie.reset_devctl & ~PCIEM_CTL_MAX_PAYLOAD) | guest_mps; if (sc->psc_pcie.has_devctl2) sc->psc_pcie.devctl2 = sc->psc_pcie.reset_devctl2; + if (sc->psc_pm.capoff != 0) + sc->psc_pm.pmcsr = sc->psc_pm.reset_pmcsr; } static int @@ -1320,6 +1338,13 @@ passthru_cfgread_default(struct passthru_softc *sc, /* Everything else just read from the device's config space. */ *rv = passthru_read_config(&sc->psc_sel, coff, bytes); + if (sc->psc_pm.capoff != 0) { + int pmcsr; + + pmcsr = sc->psc_pm.capoff + PCIR_POWER_STATUS; + *rv = passthru_cfg_overlay_field(coff, bytes, *rv, pmcsr, + sc->psc_pm.pmcsr, PASSTHRU_PMCSR_VIRT); + } if (sc->psc_pcie.capoff != 0) { int devctl; @@ -1362,8 +1387,8 @@ passthru_cfgwrite_default(struct passthru_softc *sc, struct pci_devinst *pi, int coff, int bytes, uint32_t val) { uint32_t flr_mask, transport_mask; - uint16_t physical_devctl; - int devctl, devctl2, host_mps, guest_mrrs; + uint16_t physical_devctl, physical_pmcsr; + int devctl, devctl2, host_mps, guest_mrrs, pmcsr; int error, msix_table_entries, i; uint16_t cmd_old; @@ -1408,6 +1433,30 @@ passthru_cfgwrite_default(struct passthru_softc *sc, struct pci_devinst *pi, return (0); } + /* + * A physical D3hot-to-D0 transition may reset the function and clear + * Command behind bhyve's emulated copy. Keep the physical D-state + * host-owned, emulate the guest D-state, and advertise No_Soft_Reset so + * the guest does not rely on this cycle as a function reset. + */ + pmcsr = sc->psc_pm.capoff + PCIR_POWER_STATUS; + if (sc->psc_pm.capoff != 0 && coff < pmcsr + 2 && + coff + bytes > pmcsr) { + physical_pmcsr = passthru_read_config(&sc->psc_sel, pmcsr, 2); + if (physical_pmcsr == 0xffff) { + warnx("configuration space unavailable for passthru " + "device %d/%d/%d", sc->psc_sel.pc_bus, + sc->psc_sel.pc_dev, sc->psc_sel.pc_func); + return (0); + } + passthru_cfg_update_field(coff, bytes, val, pmcsr, + PCIM_PSTAT_DMASK, &sc->psc_pm.pmcsr); + val = passthru_cfg_overlay_field(coff, bytes, val, pmcsr, + physical_pmcsr, PASSTHRU_PMCSR_VIRT); + passthru_write_config(&sc->psc_sel, coff, bytes, val); + return (0); + } + /* * A direct FLR would clear physical Command while the guest sees its * emulated copy remain enabled. Route FLR through ppt so it restores