The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags
@ 2026-08-21 22:15 David Matlack
  2026-08-21 23:06 ` Pali Rohár
  2026-08-24 20:37 ` Martin Mareš
  0 siblings, 2 replies; 8+ messages in thread
From: David Matlack @ 2026-08-21 22:15 UTC (permalink / raw)
  To: Martin Mares
  Cc: Pali Rohár, David Matlack, linux-pci, linux-kernel,
	Bjorn Helgaas

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@google.com>
---
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@google.com/

 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


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags
  2026-08-21 22:15 [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags David Matlack
@ 2026-08-21 23:06 ` Pali Rohár
  2026-08-24 16:24   ` David Matlack
  2026-08-24 20:37 ` Martin Mareš
  1 sibling, 1 reply; 8+ messages in thread
From: Pali Rohár @ 2026-08-21 23:06 UTC (permalink / raw)
  To: David Matlack; +Cc: Martin Mares, linux-pci, linux-kernel, Bjorn Helgaas

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.

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@google.com>
> ---
> 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@google.com/
> 
>  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
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags
  2026-08-21 23:06 ` Pali Rohár
@ 2026-08-24 16:24   ` David Matlack
  2026-08-24 17:36     ` Pali Rohár
  0 siblings, 1 reply; 8+ messages in thread
From: David Matlack @ 2026-08-24 16:24 UTC (permalink / raw)
  To: Pali Rohár; +Cc: Martin Mares, linux-pci, linux-kernel, Bjorn Helgaas

On Fri, Aug 21, 2026 at 4:06 PM Pali Rohár <pali@kernel.org> 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.

> 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@google.com>
> > ---
> > 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@google.com/
> >
> >  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
> >
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags
  2026-08-24 16:24   ` David Matlack
@ 2026-08-24 17:36     ` Pali Rohár
  2026-08-24 20:22       ` David Matlack
  0 siblings, 1 reply; 8+ messages in thread
From: Pali Rohár @ 2026-08-24 17:36 UTC (permalink / raw)
  To: David Matlack; +Cc: Martin Mares, linux-pci, linux-kernel, Bjorn Helgaas

On Monday 24 August 2026 09:24:33 David Matlack wrote:
> On Fri, Aug 21, 2026 at 4:06 PM Pali Rohár <pali@kernel.org> 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.

> > 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@google.com>
> > > ---
> > > 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@google.com/
> > >
> > >  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
> > >
> >

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags
  2026-08-24 17:36     ` Pali Rohár
@ 2026-08-24 20:22       ` David Matlack
  2026-08-24 20:34         ` Pali Rohár
  0 siblings, 1 reply; 8+ messages in thread
From: David Matlack @ 2026-08-24 20:22 UTC (permalink / raw)
  To: Pali Rohár; +Cc: Martin Mares, linux-pci, linux-kernel, Bjorn Helgaas

On Mon, Aug 24, 2026 at 10:36 AM Pali Rohár <pali@kernel.org> 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@kernel.org> 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@google.com>
> > > > ---
> > > > 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@google.com/
> > > >
> > > >  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
> > > >
> > >

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags
  2026-08-24 20:22       ` David Matlack
@ 2026-08-24 20:34         ` Pali Rohár
  2026-08-24 20:58           ` David Matlack
  0 siblings, 1 reply; 8+ messages in thread
From: Pali Rohár @ 2026-08-24 20:34 UTC (permalink / raw)
  To: David Matlack; +Cc: Martin Mares, linux-pci, linux-kernel, Bjorn Helgaas

On Monday 24 August 2026 13:22:32 David Matlack wrote:
> On Mon, Aug 24, 2026 at 10:36 AM Pali Rohár <pali@kernel.org> 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@kernel.org> 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.

I see. Those flags cannot be read from the PCI config space and they
need to be provided by OS when it is doing enumeration / setup of PCI.
So lspci -x dump outputs will not provide them.

> >
> > > > 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@google.com>
> > > > > ---
> > > > > 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@google.com/
> > > > >
> > > > >  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
> > > > >
> > > >

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags
  2026-08-21 22:15 [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags David Matlack
  2026-08-21 23:06 ` Pali Rohár
@ 2026-08-24 20:37 ` Martin Mareš
  1 sibling, 0 replies; 8+ messages in thread
From: Martin Mareš @ 2026-08-24 20:37 UTC (permalink / raw)
  To: David Matlack; +Cc: Pali Rohár, linux-pci, linux-kernel, Bjorn Helgaas

Hello!

> 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@google.com>

Thanks, applied.

Unfortunately, the current system of test cases cannot handle this
type of errors, because it is based solely on parsing dumps. Maybe
we should collect sysfs subtrees instead?

				Martin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags
  2026-08-24 20:34         ` Pali Rohár
@ 2026-08-24 20:58           ` David Matlack
  0 siblings, 0 replies; 8+ messages in thread
From: David Matlack @ 2026-08-24 20:58 UTC (permalink / raw)
  To: Pali Rohár; +Cc: Martin Mares, linux-pci, linux-kernel, Bjorn Helgaas

On Mon, Aug 24, 2026 at 1:34 PM Pali Rohár <pali@kernel.org> wrote:
>
> On Monday 24 August 2026 13:22:32 David Matlack wrote:
> > On Mon, Aug 24, 2026 at 10:36 AM Pali Rohár <pali@kernel.org> 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@kernel.org> 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.
>
> I see. Those flags cannot be read from the PCI config space and they
> need to be provided by OS when it is doing enumeration / setup of PCI.
> So lspci -x dump outputs will not provide them.

lspci -x will provide enough information for lspci to determine the
bit-size of bridge windows. But when PCI_FILL_BRIDGE_BASES is set,
show_hypte1() ignores the flags in the config space and uses the
OS-provided flags instead, and that's where the bug was. So when
testing (./lspci -v -F tests/bridge-window-sizes), it outputted the
correct bridge windows with and without the fix.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-08-24 20:58 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-21 22:15 [pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags David Matlack
2026-08-21 23:06 ` Pali Rohár
2026-08-24 16:24   ` David Matlack
2026-08-24 17:36     ` Pali Rohár
2026-08-24 20:22       ` David Matlack
2026-08-24 20:34         ` Pali Rohár
2026-08-24 20:58           ` David Matlack
2026-08-24 20:37 ` Martin Mareš

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox