[pciutils PATCH v2] lspci: Determine bridge window address size from bridge_flags

David Matlack <[email protected]>
Newsgroups org.kernel.vger.linux-pci,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
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 <[email protected]>
---
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/[email protected]/

 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.