diff options
| author | Chandrakanth Patil <chandrakanth.patil@broadcom.com> | 2026-02-10 09:23:16 +0000 |
|---|---|---|
| committer | Sumit Saxena <ssaxena@FreeBSD.org> | 2026-02-10 09:30:06 +0000 |
| commit | feb0a7e19f3c2e4c7eb90668b1e3dc34b5bb6dd6 (patch) | |
| tree | 8926f5e230d6958dff7ca297d0374df405bdb034 | |
| parent | 10f91d9ff7b827aac6035e224e6ddc2c79f3a0cd (diff) | |
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
| -rw-r--r-- | sys/dev/pci/pci_iov.c | 31 |
1 files 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; + } } } |
