git: feb0a7e19f3c - main - pci_iov: Reuse downstream bridge bus window if it already covers VF bus

From: Sumit Saxena <ssaxena_at_FreeBSD.org>
Date: Tue, 10 Feb 2026 09:30:41 UTC
The branch main has been updated by ssaxena:

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

commit feb0a7e19f3c2e4c7eb90668b1e3dc34b5bb6dd6
Author:     Chandrakanth Patil <chandrakanth.patil@broadcom.com>
AuthorDate: 2026-02-10 09:23:16 +0000
Commit:     Sumit Saxena <ssaxena@FreeBSD.org>
CommitDate: 2026-02-10 09:30:06 +0000

    pci_iov: Reuse downstream bridge bus window if it already covers VF bus
    
    If the parent bridge's [secondary, subordinate] window already covers
    the VF bus (e.g., programmed by BIOS or a prior PF), skip allocating
    PCI_RES_BUS. This avoids a duplicate rman allocation in the multi-PF
    case while still allocating when growth is actually needed.
    
    Reviewed by: ssaxena
    Differential Revision: https://reviews.freebsd.org/D52163
    MFC After: 1 week
---
 sys/dev/pci/pci_iov.c | 31 +++++++++++++++++++++----------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/sys/dev/pci/pci_iov.c b/sys/dev/pci/pci_iov.c
index e0e47e11d401..0e6104fe37f2 100644
--- a/sys/dev/pci/pci_iov.c
+++ b/sys/dev/pci/pci_iov.c
@@ -735,16 +735,27 @@ pci_iov_config(struct cdev *cdev, struct pci_iov_arg *arg)
 	last_rid = first_rid + (num_vfs - 1) * rid_stride;
 
 	if (pci_get_bus(dev) != PCI_RID2BUS(last_rid)) {
-		int rid = 0;
-		uint16_t last_rid_bus = PCI_RID2BUS(last_rid);
-
-		iov->iov_bus_res = bus_alloc_resource(bus, PCI_RES_BUS, &rid,
-		    last_rid_bus, last_rid_bus, 1, RF_ACTIVE);
-		if (iov->iov_bus_res == NULL) {
-			device_printf(dev,
-			    "failed to allocate PCIe bus number for VFs\n");
-			error = ENOSPC;
-			goto out;
+		device_t pcib = device_get_parent(bus);
+		uint8_t secbus = pci_read_config(pcib, PCIR_SECBUS_1, 1);
+		uint8_t subbus = pci_read_config(pcib, PCIR_SUBBUS_1, 1);
+		uint16_t vf_bus = PCI_RID2BUS(last_rid);
+
+		/* 
+		 * XXX: This should not be directly accessing the bridge registers and does
+		 * nothing to prevent some other device from releasing this bus number while
+		 * another PF is using it.
+		 */
+		if (secbus == 0 || vf_bus < secbus || vf_bus > subbus) {
+			int rid = 0;
+
+			iov->iov_bus_res = bus_alloc_resource(bus, PCI_RES_BUS, &rid,
+							      vf_bus, vf_bus, 1, RF_ACTIVE);
+			if (iov->iov_bus_res == NULL) {
+				device_printf(dev,
+				    "failed to allocate PCIe bus number for VFs\n");
+				error = ENOSPC;
+				goto out;
+			}
 		}
 	}