Re: [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags
From: David Matlack
Date: Mon Aug 24 2026 - 16:24:24 EST
On Mon, Aug 24, 2026 at 10:36 AM Pali Rohár <pali@xxxxxxxxxx> wrote:
>
> On Monday 24 August 2026 09:24:33 David Matlack wrote:
> > On Fri, Aug 21, 2026 at 4:06 PM Pali Rohár <pali@xxxxxxxxxx> wrote:
> > >
> > > Hello! Thank you for taking this issue. I briefly checked the change and
> > > I think that this is the right way how to address that issue.
> > >
> > > Anyway, it would be nice to provide some example of config space of PCI
> > > Bridge (lspci -x) which is affected by this issue and have it in
> > > pciutils/tests/ directory.
> >
> > Ack, I will incorporate that into a v3.
>
> Feel free to send it separately. No need to have it in this one change.
Sure, I can send a 2 patch series in v3 if that's what you mean?
By the way, since lspci parsing of the pciutils/tests/ directory would
use the dump backend, which does not use PCI_FILL_BRIDGE_BASES, it
will not exercise the bug fixed by this commit. Is it still worth
adding the test case? I am happy to send it, but I'm curious how it
will be used.
>
> > > On Friday 21 August 2026 22:15:59 David Matlack wrote:
> > > > Use bridge_flags to determine address size bits (16- vs 32-bit for I/O,
> > > > 32- vs 64-bit for prefetchable memory) when displaying bridge ranges
> > > > populated via PCI_FILL_BRIDGE_BASES.
> > > >
> > > > Commit ccf68033a452 ("lspci: Use PCI_FILL_BRIDGE_BASES to detect if
> > > > range behind bridge is disabled or unsupported") introduced code in
> > > > show_htype1() that reads PCI_IO_RANGE_TYPE_MASK and
> > > > PCI_MEMORY_RANGE_TYPE_MASK from bridge_base_addr[]. However,
> > > > bridge_base_addr[] holds base addresses without flags, as documented in
> > > > lib/pci.h and implemented across backends like sysfs.c and
> > > > win32-cfgmgr32.c.
> > > >
> > > > Because bridge_base_addr[] does not contain configuration register flag
> > > > bits, masking the lower bits evaluates to zero. As a result, 32-bit I/O
> > > > windows are mislabeled as "[16-bit]" and 64-bit prefetchable memory
> > > > windows are mislabeled as "[32-bit]" when using PCI_FILL_BRIDGE_BASES.
> > > >
> > > > Fixes: ccf68033a452 ("lspci: Use PCI_FILL_BRIDGE_BASES to detect if range behind bridge is disabled or unsupported")
> > > > Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx>
> > > > ---
> > > > v2:
> > > > - Fix lspci.c to use bridge_flags[], per lib/pci.h, rather than
> > > > changing the behavior of just the sysfs backend (Pali Rohár)
> > > >
> > > > v1: https://lore.kernel.org/linux-pci/20260626213047.189951-1-bhelgaas@xxxxxxxxxx/
> > > >
> > > > lspci.c | 12 +++++-------
> > > > 1 file changed, 5 insertions(+), 7 deletions(-)
> > > >
> > > > diff --git a/lspci.c b/lspci.c
> > > > index 2a14303e74f6..52fd9247aefb 100644
> > > > --- a/lspci.c
> > > > +++ b/lspci.c
> > > > @@ -571,10 +571,9 @@ show_htype1(struct device *d)
> > > >
> > > > if ((p->known_fields & PCI_FILL_BRIDGE_BASES) && !io_disabled)
> > > > {
> > > > - io_base = p->bridge_base_addr[0] & PCI_IO_RANGE_MASK;
> > > > + io_base = p->bridge_base_addr[0];
> > > > io_limit = io_base + p->bridge_size[0] - 1;
> > > > - io_type = p->bridge_base_addr[0] & PCI_IO_RANGE_TYPE_MASK;
> > > > - io_bits = (io_type == PCI_IO_RANGE_TYPE_32) ? 32 : 16;
> > > > + io_bits = (p->bridge_flags[0] & PCI_IORESOURCE_IO_16BIT_ADDR) ? 16 : 32;
> > > > show_range("\tI/O behind bridge", io_base, io_limit, io_bits, io_disabled);
> > > > }
> > > > else if (io_type != (io_limit & PCI_IO_RANGE_TYPE_MASK) ||
> > > > @@ -600,7 +599,7 @@ show_htype1(struct device *d)
> > > >
> > > > if ((p->known_fields & PCI_FILL_BRIDGE_BASES) && !mem_disabled)
> > > > {
> > > > - mem_base = p->bridge_base_addr[1] & PCI_MEMORY_RANGE_MASK;
> > > > + mem_base = p->bridge_base_addr[1];
> > > > mem_limit = mem_base + p->bridge_size[1] - 1;
> > > > show_range("\tMemory behind bridge", mem_base, mem_limit, 32, mem_disabled);
> > > > }
> > > > @@ -616,10 +615,9 @@ show_htype1(struct device *d)
> > > >
> > > > if ((p->known_fields & PCI_FILL_BRIDGE_BASES) && !pref_disabled)
> > > > {
> > > > - u64 pref_base_64 = p->bridge_base_addr[2] & PCI_MEMORY_RANGE_MASK;
> > > > + u64 pref_base_64 = p->bridge_base_addr[2];
> > > > u64 pref_limit_64 = pref_base_64 + p->bridge_size[2] - 1;
> > > > - pref_type = p->bridge_base_addr[2] & PCI_MEMORY_RANGE_TYPE_MASK;
> > > > - pref_bits = (pref_type == PCI_PREF_RANGE_TYPE_64) ? 64 : 32;
> > > > + pref_bits = (p->bridge_flags[2] & PCI_IORESOURCE_MEM_64) ? 64 : 32;
> > > > show_range("\tPrefetchable memory behind bridge", pref_base_64, pref_limit_64, pref_bits, pref_disabled);
> > > > }
> > > > else if (pref_type != (pref_limit & PCI_PREF_RANGE_TYPE_MASK) ||
> > > >
> > > > base-commit: b41ce14da749fb44ca7940ba9797027bfa62c23e
> > > > --
> > > > 2.55.0.766.g2966f0265a-goog
> > > >
> > >