Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

PCI: Prevent assignment to unsupported bridge windows

Previously, pci_read_bridge_io() and pci_read_bridge_mmio_pref()
unconditionally set resource type flags (IORESOURCE_IO or IORESOURCE_MEM |
IORESOURCE_PREFETCH) when reading bridge window registers. For windows that
are not implemented in hardware, this may cause the allocator to assign
space for a window that doesn't exist.

For example, the EcoNET EN7528 SoC Root Port doesn't support the
prefetchable window, but since a downstream device had a prefetchable BAR,
the allocator mistakenly assigned a prefetchable window:

pci 0001:00:01.0: [14c3:0811] type 01 class 0x060400 PCIe Root Port
pci 0001:00:01.0: PCI bridge to [bus 01-ff]
pci 0001:00:01.0: bridge window [mem 0x28000000-0x280fffff]: assigned
pci 0001:00:01.0: bridge window [mem 0x28100000-0x282fffff pref]: assigned
pci 0001:01:00.0: BAR 0 [mem 0x28100000-0x281fffff 64bit pref]: assigned

pci_read_bridge_windows() already detects unsupported windows by testing
register writability and sets dev->io_window/pref_window accordingly.

Check dev->io_window/pref_window so we don't set the resource flags for
unsupported windows, which prevents the allocator from assigning space to
them.

After this commit, the prefetchable BAR is correctly allocated from the
non-prefetchable window:

pci 0001:00:01.0: bridge window [mem 0x28000000-0x281fffff]: assigned
pci 0001:01:00.0: BAR 0 [mem 0x28000000-0x280fffff 64bit pref]: assigned

Suggested-by: Bjorn Helgaas <helgaas@kernel.org>
Link: https://lore.kernel.org/all/20260113210259.GA715789@bhelgaas/
Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260312165332.569772-4-cjd@cjdns.fr

authored by

Ahmed Naseef and committed by
Bjorn Helgaas
92427ab4 6de23f81

+6
+6
drivers/pci/probe.c
··· 395 395 unsigned long io_mask, io_granularity, base, limit; 396 396 struct pci_bus_region region; 397 397 398 + if (!dev->io_window) 399 + return; 400 + 398 401 io_mask = PCI_IO_RANGE_MASK; 399 402 io_granularity = 0x1000; 400 403 if (dev->io_window_1k) { ··· 467 464 u64 base64, limit64; 468 465 pci_bus_addr_t base, limit; 469 466 struct pci_bus_region region; 467 + 468 + if (!dev->pref_window) 469 + return; 470 470 471 471 pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); 472 472 pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);