]> www.infradead.org Git - users/hch/misc.git/commitdiff
PCI: Fix pdev_resources_assignable() disparity
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Mon, 30 Jun 2025 14:26:40 +0000 (17:26 +0300)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 16 Sep 2025 16:18:23 +0000 (11:18 -0500)
pdev_sort_resources() uses pdev_resources_assignable() helper to decide if
device's resources cannot be assigned, so it ignores class 0
(PCI_CLASS_NOT_DEFINED) devices. pbus_size_mem(), on the other hand, does
not do the same check. This could lead into a situation where a resource
ends up on realloc_head list but is not on the head list, which in turn
prevents emptying the resource from the realloc_head list in
__assign_resources_sorted().

A non-empty realloc_head is unacceptable because it triggers an internal
sanity check as shown in this log with a device that has class 0
(PCI_CLASS_NOT_DEFINED):

  pci 0001:01:00.0: [144d:a5a5] type 00 class 0x000000 PCIe Endpoint
  pci 0001:01:00.0: BAR 0 [mem 0x00000000-0x000fffff 64bit]
  pci 0001:01:00.0: ROM [mem 0x00000000-0x0000ffff pref]
  pcieport 0001:00:00.0: bridge window [mem 0x00100000-0x001fffff] to [bus 01-ff] add_size 100000 add_align 100000
  pcieport 0001:00:00.0: bridge window [mem 0x40000000-0x401fffff]: assigned
  ------------[ cut here ]------------
  kernel BUG at drivers/pci/setup-bus.c:2532!
  Internal error: Oops - BUG: 00000000f2000800 [#1]  SMP
  ...
  Call trace:
   pci_assign_unassigned_bus_resources+0x110/0x114 (P)
   pci_rescan_bus+0x28/0x48

Use pdev_resources_assignable() also within pbus_size_mem() to skip
processing of non-assignable resources which removes the disparity in
between what resources pdev_sort_resources() and pbus_size_mem() consider.
As non-assignable resources are no longer processed, they are not added to
the realloc_head list, thus the sanity check no longer triggers.

This disparity problem is very old but only now became apparent after
2499f5348431 ("PCI: Rework optional resource handling") that made the ROM
resources optional when calculating bridge window sizes which required
adding the resource to the realloc_head list.  Previously, bridge windows
were just sized larger than necessary.

Fixes: 2499f5348431 ("PCI: Rework optional resource handling")
Reported-by: Tudor Ambarus <tudor.ambarus@linaro.org>
Closes: https://lore.kernel.org/all/5f103643-5e1c-43c6-b8fe-9617d3b5447c@linaro.org/
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org # v6.15+
Link: https://patch.msgid.link/20250822123359.16305-3-ilpo.jarvinen@linux.intel.com
drivers/pci/setup-bus.c

index 527f0479e983cfb411f2062bfa9aef17e02d4239..df5aec46c29d94ff0c77a028706ed7ce30d32fbe 100644 (file)
@@ -1191,6 +1191,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
                        resource_size_t r_size;
 
                        if (r->parent || (r->flags & IORESOURCE_PCI_FIXED) ||
+                           !pdev_resources_assignable(dev) ||
                            ((r->flags & mask) != type &&
                             (r->flags & mask) != type2 &&
                             (r->flags & mask) != type3))