[PATCH] PCI: Fix PCI bridge resource allocation when base exceeds limit

Sizhe Liu
2026-02-03T02:35:55Z

In pci_read_bridge_mmio_pref(), pci_read_bridge_mmio() and pci_read_bridge_io(),
when the MEMORY_BASE value is greater than MEMORY_LIMIT,
resource_set_range(res, 0, 0) is called to set both the start address
and the size of the address of the PCI bridge resource to 0.
However, the end address is later calculated as:
res->end = res->start + size - 1
As a result, the resource range becomes [0x00000000-0xffffffffffffffff]
instead of the expected [0x00000000-0x00000000].

This causes an exception in the subsequent resource claiming process,
because the address range [0x00000000-0xffffffffffffffff] exceeds
the range specified in the DSDT. The abnormal bridge triggers clipping
when claiming resources, then the entire parent PCI bus address range
becomes occupied. Other bridges on the same bus will report
address conflicts during their claim process. The resource allocation
may be degraded from 64-bit to 32-bit, or even worse, it fails.

The related boot log is as follows:
pci 0000:20:00.0: PCI bridge to [bus 21]
pci 0000:20:00.0: bridge window [io size 0x0000 disabled]: can't claim; no address assigned
pci 0000:20:00.0: [io 0x0000-0xffffffffffffffff disabled] clipped to [io 0x0000-0xffff disabled]
pci 0000:20:00.0: bridge window [io 0x0000-0xffff disabled]
pci 0000:20:00.0: bridge window [mem size 0x00000000 disabled]: can't claim; no address assigned
pci 0000:20:00.0: [mem 0x00000000-0xffffffffffffffff disabled] clipped to [mem 0x800000000000-0x8013ffffffff disabled]
pci 0000:20:00.0: bridge window [mem 0x800000000000-0x8013ffffffff disabled]: can't claim; no compatible bridge window
pci 0000:20:00.0: bridge window [mem size 0x00000000 64bit pref disabled]: can't claim; no address assigned
pci 0000:20:00.0: [mem 0x00000000-0xffffffffffffffff 64bit pref disabled] clipped to [mem 0x800000000000-0x8013ffffffff 64bit pref disabled]
pci 0000:20:00.0: bridge window [mem 0x800000000000-0x8013ffffffff 64bit pref disabled]
pci 0000:20:08.0: PCI bridge to [bus 22]
pci 0000:20:08.0: bridge window [io size 0x0000 disabled]: can't claim; no address assigned
pci 0000:20:08.0: [io 0x0000-0xffffffffffffffff disabled] clipped to [io 0x0000-0xffff disabled]
pci 0000:20:08.0: bridge window [io 0x0000-0xffff disabled]: can't claim; address conflict with PCI Bus 0000:21 [io 0x0000-0xffff disabled]
pci 0000:20:08.0: bridge window [mem size 0x00000000 disabled]: can't claim; no address assigned
pci 0000:20:08.0: [mem 0x00000000-0xffffffffffffffff disabled] clipped to [mem 0x800000000000-0x8013ffffffff disabled]
pci 0000:20:08.0: bridge window [mem 0x800000000000-0x8013ffffffff disabled]: can't claim; no compatible bridge window
pci 0000:20:08.0: bridge window [mem size 0x00000000 64bit pref disabled]: can't claim; no address assigned
pci 0000:20:08.0: [mem 0x00000000-0xffffffffffffffff 64bit pref disabled] clipped to [mem 0x800000000000-0x8013ffffffff 64bit pref disabled]
pci 0000:20:08.0: bridge window [mem 0x800000000000-0x8013ffffffff 64bit pref disabled]: can't claim; address conflict with PCI Bus 0000:21 [mem 0x800000000000-0x8013ffffffff 64bit pref disabled]
pci 0000:20:09.0: PCI bridge to [bus 23]
pci 0000:20:09.0: bridge window [io 0x0000-0x0fff]: can't claim; address conflict with PCI Bus 0000:21 [io 0x0000-0xffff disabled]
pci 0000:20:09.0: bridge window [mem 0x800003000000-0x8000048fffff 64bit pref]: can't claim; address conflict with PCI Bus 0000:21 [mem 0x800000000000-0x8013ffffffff 64bit pref disabled]

Solution:
A comment in pci_read_bridge_mmio_pref() states:
/*
* Some bridges set the base > limit by default, and some
* (broken) BIOSes do not initialize them. If we find
* this, just assume they are not being used.
*/
When the base is greater than the limit, a proper fix is to set the
resource flag to IORESOURCE_UNSET or IORESOURCE_DISABLED while keeping
the start and end addresses as 0. This prevents the clipping process
from being triggered incorrectly.

Fixes: 8278c6914306 ("PCI: Preserve bridge window resource type flags")
Signed-off-by: Sizhe Liu <liusizhe5@huawei.com>
---
drivers/pci/probe.c | 3 ---
1 file changed, 3 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 41183aed8f5d..561f2420d9eb 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -429,7 +429,6 @@ static void pci_read_bridge_io(struct pci_dev *dev, struct resource *res,
if (log)
pci_info(dev, " bridge window %pR\n", res);
} else {
- resource_set_range(res, 0, 0);
res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
}
}
@@ -455,7 +454,6 @@ static void pci_read_bridge_mmio(struct pci_dev *dev, struct resource *res,
if (log)
pci_info(dev, " bridge window %pR\n", res);
} else {
- resource_set_range(res, 0, 0);
res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
}
}
@@ -511,7 +509,6 @@ static void pci_read_bridge_mmio_pref(struct pci_dev *dev, struct resource *res,
if (log)
pci_info(dev, " bridge window %pR\n", res);
} else {
- resource_set_range(res, 0, 0);
res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
}
}
--
2.33.0