git: e1b0391424c6 - stable/14 - pci: Do not reconcile MPS across PCI domains

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a879f8c.24577.6789887d__12932.2658571013$1787273285$gmane$org@gitrepo.freebsd.org>
The branch stable/14 has been updated by kbowling:

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

commit e1b0391424c6cf44cc0756547a4506e5cf49fd82
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-14 05:16:41 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-21 00:44:32 +0000

    pci: Do not reconcile MPS across PCI domains
    
    A PCI function can provide a host bridge into a synthetic PCI domain.
    Intel VMD does this: the host facing VMD function remains in its
    original domain while the hidden Root Ports and endpoints appear in a
    separate domain.  The VMD function's Device Control does not describe
    an upstream link in that synthetic hierarchy.
    
    The hierarchy wide cold pass incorrectly used the VMD function's MPS
    to reprogram the hidden ports and their endpoints.  Stop both cold
    reconciliation and runtime path walks at a PCI domain boundary.  The
    real Root Ports within the VMD domain continue to reconcile their
    endpoints normally.
    
    Reviewed by:    imp
    Tested by:      Michael Butler <[email protected]>
    Fixes:          8e9fe9996a1f ("pci: Reconcile MPS before attaching PCIe devices")
    Sponsored by:   BBOX.io
    Differential Revision:  https://reviews.freebsd.org/D58837
    
    (cherry picked from commit 57293f4541cdea8e4158f751a4439f69b3ec1711)
---
 sys/dev/pci/pci.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 714e0498294f..e96508ab0fe8 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -4468,6 +4468,13 @@ pcie_path_mps(device_t dev, uint16_t *mpsp)
 		pcib = device_get_parent(bus);
 		if (pcib == NULL || !is_pci_device(pcib))
 			break;
+		/*
+		 * A PCI function may expose a host bridge for a synthetic PCI
+		 * domain.  Its Device Control belongs to the parent domain and
+		 * does not describe an upstream link in the synthetic hierarchy.
+		 */
+		if (pci_get_domain(pcib) != pci_get_domain(dev))
+			break;
 		dinfo = device_get_ivars(pcib);
 		if (dinfo->cfg.pcie.pcie_location != 0) {
 			mps = pcie_read_config(pcib, PCIER_DEVICE_CTL, 2) &
@@ -4685,6 +4692,13 @@ pcie_reconcile_link_mps(device_t bus)
 	pcib = device_get_parent(bus);
 	if (!is_pci_device(pcib))
 		return;
+	/*
+	 * A PCI function may provide a host bridge into a separate domain,
+	 * as Intel VMD does.  Do not treat the function's host-facing PCIe
+	 * Device Control as the upstream end of a link in the child domain.
+	 */
+	if (pci_get_domain(pcib) != pcib_get_domain(bus))
+		return;
 	upinfo = device_get_ivars(pcib);
 	if (upinfo->cfg.pcie.pcie_location == 0)
 		return;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.