[PATCH 0/2] PCI: Guard against NULL bus->self on SR-IOV virtual buses

From: Yuguo Li

Date: Wed Jun 10 2026 - 10:07:44 EST


Hi Bjorn, all,

This series fixes two NULL pointer dereferences in the PCI core that are
hit on x86_64 with SR-IOV PFs whose VFs span more than one bus number,
once anything pokes those VFs through paths that walk up through their
parent bus.

Background
==========

When a VF allocated by pci_iov_add_virtfn() lands on a bus number
different from its PF, virtfn_add_bus() calls

pci_add_new_bus(parent, NULL, busnr)

producing a struct pci_bus with a valid ->parent but no bridge device
(->self == NULL). include/linux/pci.h already documents this:

/*
* Note: we'd love to have a "device" pointer here, but
* we can't have it. ... See virtfn_add_bus() for an
* example of a bus without a device.
*/

The MSI IRQ domain path was taught about this case years ago by

38ea72bdb65d ("PCI/MSI: Fix MSI IRQ domains for VFs on virtual buses")

but other paths in drivers/pci/ that follow bus->self were not updated
in step. Two of them have been observable for a long time but only
trip on configurations where a VF actually crosses a bus boundary AND
something (sysfs rescan, resource reallocation, etc.) reaches them on
that virtual bus -- which is not exercised by routine boot.

What trips
==========

Patch 1/2 - drivers/pci/probe.c::pci_read_bridge_bases()

Only guards pci_is_root_bus(child). Reached on x86 via
pcibios_fixup_bus() during pci_rescan_bus() on a virtual bus
(bus->is_added stays 0 because the SR-IOV add path never invokes
pci_scan_child_bus_*()). Dereferences child->self at the
pci_info()/dev->transparent site.

Fixes: f92d4e29d785 ("PCI: fix wrong assumption in
pci_read_bridge_bases")

Patch 2/2 - drivers/pci/setup-res.c::_pci_assign_resource()

Walks up parent buses retrying allocation; loop termination is
"if (!bus->parent || !bus->self->transparent) break;". For a
virtual bus the !bus->parent test fails (parent is real), then
bus->self->transparent NULL-derefs.

Fixes: d09ee9687e02 ("PCI: improve resource allocation under
transparent bridges")

Reproducer
==========

- x86_64, mainline v7.1-rc7+
- any SR-IOV-capable PF whose sriov_numvfs is large enough that at
least one VF crosses to a new bus number (mlx5, i40e, ixgbe, igb,
bnxt, ...)
- LTP testcases/bin/tpci is one off-the-shelf trigger: its
test_scan_bus subtest reaches patch 1 via pci_rescan_bus(), and
the resource-assignment subtest reaches patch 2 via
pci_assign_resource().

Without this series, tpci panics within seconds. With both patches
applied to the same tree, tpci completes its full PCI subtest matrix
on the same hardware without splatting.

Patches
=======

Yuguo Li (2):
PCI: Bail out of pci_read_bridge_bases() for SR-IOV virtual buses
PCI: setup-res: Guard against bus->self == NULL in
_pci_assign_resource()

drivers/pci/probe.c | 10 ++++++++++
drivers/pci/setup-res.c | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)

--
2.43.7