]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[pci] Ignore invalid subordinate bus numbers 1619/head
authorMichael Brown <mcb30@ipxe.org>
Thu, 5 Feb 2026 11:58:01 +0000 (11:58 +0000)
committerMichael Brown <mcb30@ipxe.org>
Thu, 5 Feb 2026 12:09:59 +0000 (12:09 +0000)
Some systems (observed on a Dell C6615) fail to correctly populate the
subordinate PCI bus number on some PCI bridges.  We do not currently
guard against this behaviour, causing us to subsequently scan through
a huge expanse of the PCI bus:dev.fn address range.

Fix by ignoring the subordinate bus number if it is lower than the
bridge's own bus number.

Reported-by: Anisse Astier <an.astier@criteo.com>
Reported-by: Ahmad Mahagna <ahmhad@nvidia.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/bus/pci.c

index 30163300a976259e526d6e5998d6f93946b7edec..15d2da0888c1f76811ac017a7159eff80030ead0 100644 (file)
@@ -352,13 +352,20 @@ int pci_find_next ( struct pci_device *pci, uint32_t *busdevfn ) {
                hdrtype &= PCI_HEADER_TYPE_MASK;
                if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
                        pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
-                       end = PCI_BUSDEVFN ( PCI_SEG ( *busdevfn ),
-                                            ( sub + 1 ), 0, 0 );
-                       count = ( end - range.start );
-                       if ( count > range.count ) {
-                               DBGC ( pci, PCI_FMT " found subordinate bus "
-                                      "%#02x\n", PCI_ARGS ( pci ), sub );
-                               range.count = count;
+                       if ( sub <= PCI_BUS ( *busdevfn ) ) {
+                               DBGC ( pci, PCI_FMT " ignoring invalid "
+                                      "subordinate bus %#02x\n",
+                                      PCI_ARGS ( pci ), sub );
+                       } else {
+                               end = PCI_BUSDEVFN ( PCI_SEG ( *busdevfn ),
+                                                    ( sub + 1 ), 0, 0 );
+                               count = ( end - range.start );
+                               if ( count > range.count ) {
+                                       DBGC ( pci, PCI_FMT " found "
+                                              "subordinate bus %#02x\n",
+                                              PCI_ARGS ( pci ), sub );
+                                       range.count = count;
+                               }
                        }
                }