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
This commit is contained in:
Chandrakanth Patil
2026-02-10 09:23:16 +00:00
committed by Sumit Saxena
parent 10f91d9ff7
commit feb0a7e19f
+20 -9
View File
@@ -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);
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);
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;
/*
* 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;
}
}
}