public inbox for linux-pci@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] PCI: Fix PCI bridge resource allocation when base exceeds limit
@ 2026-02-03  2:35 Sizhe Liu
  2026-02-03 15:14 ` Ilpo Järvinen
  0 siblings, 1 reply; 6+ messages in thread
From: Sizhe Liu @ 2026-02-03  2:35 UTC (permalink / raw)
  To: bhelgaas, ilpo.jarvinen, jonathan.cameron, shiju.jose
  Cc: linux-pci, linuxarm, prime.zeng, fanghao11, shenyang39, liusizhe5

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


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

* Re: [PATCH] PCI: Fix PCI bridge resource allocation when base exceeds limit
  2026-02-03  2:35 [PATCH] PCI: Fix PCI bridge resource allocation when base exceeds limit Sizhe Liu
@ 2026-02-03 15:14 ` Ilpo Järvinen
  2026-02-03 17:21   ` Ilpo Järvinen
  2026-02-04  3:58   ` Sizhe LIU
  0 siblings, 2 replies; 6+ messages in thread
From: Ilpo Järvinen @ 2026-02-03 15:14 UTC (permalink / raw)
  To: Sizhe Liu
  Cc: bhelgaas, jonathan.cameron, shiju.jose, linux-pci, linuxarm,
	prime.zeng, fanghao11, shenyang39

On Tue, 3 Feb 2026, Sizhe Liu wrote:

> 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].

Hi,

Thanks for the patch but your understanding on how resources addresses 
work is not correct.

A zero sized resource should have end at start - 1, just like 
resource_set_range() sets it!

> 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_bus_clip_resource() should not touch IORESOURCE_DISABLED resources 
nor zero sized resources. The problem seems to originate from 
pci_claim_bridge_resources() and pci_claim_bridge_resource() which try to 
claim such resources no matter what.

I think pci_claim_bridge_resources() should check if IORESOURCE_DISABLED 
is set and use continue, it already has check !r->flags which probably 
worked prior to 8278c6914306 ("PCI: Preserve bridge window resource type 
flags") but is no longer enough to decided if bridge window is valid or 
not.

Do you want to do that patch and test it? (I'm quite busy this week 
myself.)

> 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;
>  	}
>  }


-- 
 i.


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

* Re: [PATCH] PCI: Fix PCI bridge resource allocation when base exceeds limit
  2026-02-03 15:14 ` Ilpo Järvinen
@ 2026-02-03 17:21   ` Ilpo Järvinen
  2026-02-04  8:56     ` Sizhe LIU
  2026-02-06 22:17     ` Bjorn Helgaas
  2026-02-04  3:58   ` Sizhe LIU
  1 sibling, 2 replies; 6+ messages in thread
From: Ilpo Järvinen @ 2026-02-03 17:21 UTC (permalink / raw)
  To: Sizhe Liu
  Cc: bhelgaas, jonathan.cameron, shiju.jose, linux-pci, linuxarm,
	prime.zeng, fanghao11, shenyang39

[-- Attachment #1: Type: text/plain, Size: 4944 bytes --]

On Tue, 3 Feb 2026, Ilpo Järvinen wrote:

> On Tue, 3 Feb 2026, Sizhe Liu wrote:
> 
> > 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].
> 
> Hi,
> 
> Thanks for the patch but your understanding on how resources addresses 
> work is not correct.
> 
> A zero sized resource should have end at start - 1, just like 
> resource_set_range() sets it!
> 
> > 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_bus_clip_resource() should not touch IORESOURCE_DISABLED resources 
> nor zero sized resources. The problem seems to originate from 
> pci_claim_bridge_resources() and pci_claim_bridge_resource() which try to 
> claim such resources no matter what.
> 
> I think pci_claim_bridge_resources() should check if IORESOURCE_DISABLED 
> is set and use continue, it already has check !r->flags which probably 
> worked prior to 8278c6914306 ("PCI: Preserve bridge window resource type 
> flags") but is no longer enough to decided if bridge window is valid or 
> not.
> 
> Do you want to do that patch and test it? (I'm quite busy this week 
> myself.)

I managed to get the patch done:

--
From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>
Date: Tue, 3 Feb 2026 19:14:30 +0200
Subject: [PATCH 1/1] PCI: Don't claim disabled bridge windows
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The commit 8278c6914306 ("PCI: Preserve bridge window resource type
flags") change bridge window resource behavior such that flags are no
longer zero if the bridge window is not valid or is disabled (mainly
to preserve the type flags for later use). If a bridge window has its
limit smaller than base address, pci_read_bridge_*() sets both
IORESOURCE_UNSET and IORESOURCE_DISABLED to indicate the bridge window
exists but is not valid with the current base and limit configuration.

The code in pci_claim_bridge_resources() still depends on the old
behavior be checking validity of the bridge window solely based on
!r->flags, whereas after the commit 8278c6914306 ("PCI: Preserve bridge
window resource type flags"), also IORESOURCE_DISABLED may indicate
bridge window addresses are not valid.

While pci_claim_resource() does check IORESOURCE_UNSET,
pci_claim_bridge_resource() does attempt to clip the resource if
pci_claim_resource() fails which is not correct for not valid bridge
window resource. As pci_bus_clip_resource() performs clipping
regardless flags and then clears IORESOURCE_UNSET, it should not be
called for not valid resources.

The problem is visible in this log:

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]

Add IORESOURCE_DISABLED check into pci_claim_bridge_resources() to
only claim bridge windows that appear to have a valid configuration.

Reported-by: Sizhe Liu <liusizhe5@huawei.com>
Fixes: 8278c6914306 ("PCI: Preserve bridge window resource type flags")
Cc: <stable@vger.kernel.org>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/pci/setup-bus.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 6e90f46f52af..43ea635e1ea8 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1733,6 +1733,8 @@ static void pci_claim_bridge_resources(struct pci_dev *dev)
 
 		if (!r->flags || r->parent)
 			continue;
+		if (r->flags & IORESOURCE_DISABLED)
+			continue;
 
 		pci_claim_bridge_resource(dev, i);
 	}

base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
-- 
2.39.5

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

* Re: [PATCH] PCI: Fix PCI bridge resource allocation when base exceeds limit
  2026-02-03 15:14 ` Ilpo Järvinen
  2026-02-03 17:21   ` Ilpo Järvinen
@ 2026-02-04  3:58   ` Sizhe LIU
  1 sibling, 0 replies; 6+ messages in thread
From: Sizhe LIU @ 2026-02-04  3:58 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: bhelgaas, jonathan.cameron, shiju.jose, linux-pci, linuxarm,
	prime.zeng, fanghao11, shenyang39


On 2026/2/3 23:14, Ilpo Järvinen wrote:
> On Tue, 3 Feb 2026, Sizhe Liu wrote:
>
>> 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].
> Hi,
>
> Thanks for the patch but your understanding on how resources addresses
> work is not correct.
>
> A zero sized resource should have end at start - 1, just like
> resource_set_range() sets it!

Hi,

Thanks for your correction! I agree with you.

Use [0x00000000-0xffffffffffffffff] to represent a zero-length

resource address, even though it may look misleading.

If the zero-length resource address is represented as 
[0x00000000-0x00000000],

the size returned by resource_size() would be 1, which is incorrect.

>> 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_bus_clip_resource() should not touch IORESOURCE_DISABLED resources
> nor zero sized resources. The problem seems to originate from
> pci_claim_bridge_resources() and pci_claim_bridge_resource() which try to
> claim such resources no matter what.
>
> I think pci_claim_bridge_resources() should check if IORESOURCE_DISABLED
> is set and use continue, it already has check !r->flags which probably
> worked prior to 8278c6914306 ("PCI: Preserve bridge window resource type
> flags") but is no longer enough to decided if bridge window is valid or
> not.
>
> Do you want to do that patch and test it? (I'm quite busy this week
> myself.)
No problem, I've seen your patch and I will test it later.
>> 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;
>>   	}
>>   }
>

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

* Re: [PATCH] PCI: Fix PCI bridge resource allocation when base exceeds limit
  2026-02-03 17:21   ` Ilpo Järvinen
@ 2026-02-04  8:56     ` Sizhe LIU
  2026-02-06 22:17     ` Bjorn Helgaas
  1 sibling, 0 replies; 6+ messages in thread
From: Sizhe LIU @ 2026-02-04  8:56 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: bhelgaas, jonathan.cameron, shiju.jose, linux-pci, linuxarm,
	prime.zeng, fanghao11, shenyang39


On 2026/2/4 1:21, Ilpo Järvinen wrote:
> On Tue, 3 Feb 2026, Ilpo Järvinen wrote:
>
>> On Tue, 3 Feb 2026, Sizhe Liu wrote:
>>
>>> 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].
>> Hi,
>>
>> Thanks for the patch but your understanding on how resources addresses
>> work is not correct.
>>
>> A zero sized resource should have end at start - 1, just like
>> resource_set_range() sets it!
>>
>>> 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_bus_clip_resource() should not touch IORESOURCE_DISABLED resources
>> nor zero sized resources. The problem seems to originate from
>> pci_claim_bridge_resources() and pci_claim_bridge_resource() which try to
>> claim such resources no matter what.
>>
>> I think pci_claim_bridge_resources() should check if IORESOURCE_DISABLED
>> is set and use continue, it already has check !r->flags which probably
>> worked prior to 8278c6914306 ("PCI: Preserve bridge window resource type
>> flags") but is no longer enough to decided if bridge window is valid or
>> not.
>>
>> Do you want to do that patch and test it? (I'm quite busy this week
>> myself.)
> I managed to get the patch done:
>
> --
> From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>
> Date: Tue, 3 Feb 2026 19:14:30 +0200
> Subject: [PATCH 1/1] PCI: Don't claim disabled bridge windows
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> The commit 8278c6914306 ("PCI: Preserve bridge window resource type
> flags") change bridge window resource behavior such that flags are no
> longer zero if the bridge window is not valid or is disabled (mainly
> to preserve the type flags for later use). If a bridge window has its
> limit smaller than base address, pci_read_bridge_*() sets both
> IORESOURCE_UNSET and IORESOURCE_DISABLED to indicate the bridge window
> exists but is not valid with the current base and limit configuration.
>
> The code in pci_claim_bridge_resources() still depends on the old
> behavior be checking validity of the bridge window solely based on
> !r->flags, whereas after the commit 8278c6914306 ("PCI: Preserve bridge
> window resource type flags"), also IORESOURCE_DISABLED may indicate
> bridge window addresses are not valid.
>
> While pci_claim_resource() does check IORESOURCE_UNSET,
> pci_claim_bridge_resource() does attempt to clip the resource if
> pci_claim_resource() fails which is not correct for not valid bridge
> window resource. As pci_bus_clip_resource() performs clipping
> regardless flags and then clears IORESOURCE_UNSET, it should not be
> called for not valid resources.
>
> The problem is visible in this log:
>
> 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]
>
> Add IORESOURCE_DISABLED check into pci_claim_bridge_resources() to
> only claim bridge windows that appear to have a valid configuration.
>
> Reported-by: Sizhe Liu <liusizhe5@huawei.com>
> Fixes: 8278c6914306 ("PCI: Preserve bridge window resource type flags")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
>   drivers/pci/setup-bus.c | 2 ++
>   1 file changed, 2 insertions(+)
>
> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
> index 6e90f46f52af..43ea635e1ea8 100644
> --- a/drivers/pci/setup-bus.c
> +++ b/drivers/pci/setup-bus.c
> @@ -1733,6 +1733,8 @@ static void pci_claim_bridge_resources(struct pci_dev *dev)
>   
>   		if (!r->flags || r->parent)
>   			continue;
> +		if (r->flags & IORESOURCE_DISABLED)
> +			continue;
>   
>   		pci_claim_bridge_resource(dev, i);
>   	}
>
> base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
Thanks for your feedback! I've tested this patch and it functions well, 
so go ahead with it.

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

* Re: [PATCH] PCI: Fix PCI bridge resource allocation when base exceeds limit
  2026-02-03 17:21   ` Ilpo Järvinen
  2026-02-04  8:56     ` Sizhe LIU
@ 2026-02-06 22:17     ` Bjorn Helgaas
  1 sibling, 0 replies; 6+ messages in thread
From: Bjorn Helgaas @ 2026-02-06 22:17 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Sizhe Liu, bhelgaas, jonathan.cameron, shiju.jose, linux-pci,
	linuxarm, prime.zeng, fanghao11, shenyang39

On Tue, Feb 03, 2026 at 07:21:38PM +0200, Ilpo Järvinen wrote:
> On Tue, 3 Feb 2026, Ilpo Järvinen wrote:
> 
> > On Tue, 3 Feb 2026, Sizhe Liu wrote:
> > 
> > > 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].
> > 
> > Hi,
> > 
> > Thanks for the patch but your understanding on how resources addresses 
> > work is not correct.
> > 
> > A zero sized resource should have end at start - 1, just like 
> > resource_set_range() sets it!
> > 
> > > 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_bus_clip_resource() should not touch IORESOURCE_DISABLED resources 
> > nor zero sized resources. The problem seems to originate from 
> > pci_claim_bridge_resources() and pci_claim_bridge_resource() which try to 
> > claim such resources no matter what.
> > 
> > I think pci_claim_bridge_resources() should check if IORESOURCE_DISABLED 
> > is set and use continue, it already has check !r->flags which probably 
> > worked prior to 8278c6914306 ("PCI: Preserve bridge window resource type 
> > flags") but is no longer enough to decided if bridge window is valid or 
> > not.
> > 
> > Do you want to do that patch and test it? (I'm quite busy this week 
> > myself.)
> 
> I managed to get the patch done:
> 
> --
> From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>
> Date: Tue, 3 Feb 2026 19:14:30 +0200
> Subject: [PATCH 1/1] PCI: Don't claim disabled bridge windows
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> 
> The commit 8278c6914306 ("PCI: Preserve bridge window resource type
> flags") change bridge window resource behavior such that flags are no
> longer zero if the bridge window is not valid or is disabled (mainly
> to preserve the type flags for later use). If a bridge window has its
> limit smaller than base address, pci_read_bridge_*() sets both
> IORESOURCE_UNSET and IORESOURCE_DISABLED to indicate the bridge window
> exists but is not valid with the current base and limit configuration.
> 
> The code in pci_claim_bridge_resources() still depends on the old
> behavior be checking validity of the bridge window solely based on
> !r->flags, whereas after the commit 8278c6914306 ("PCI: Preserve bridge
> window resource type flags"), also IORESOURCE_DISABLED may indicate
> bridge window addresses are not valid.
> 
> While pci_claim_resource() does check IORESOURCE_UNSET,
> pci_claim_bridge_resource() does attempt to clip the resource if
> pci_claim_resource() fails which is not correct for not valid bridge
> window resource. As pci_bus_clip_resource() performs clipping
> regardless flags and then clears IORESOURCE_UNSET, it should not be
> called for not valid resources.
> 
> The problem is visible in this log:
> 
> 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]
> 
> Add IORESOURCE_DISABLED check into pci_claim_bridge_resources() to
> only claim bridge windows that appear to have a valid configuration.
> 
> Reported-by: Sizhe Liu <liusizhe5@huawei.com>
> Fixes: 8278c6914306 ("PCI: Preserve bridge window resource type flags")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

Applied to pci/resource for v6.20, thanks!

FWIW, when applied to this message, b4 extracts Sizhe's original
patch, which isn't what we want in this case:

  $ b4 am -om/ https://lore.kernel.org/all/4d9228d6-a230-6ddf-e300-fbf42d523863@linux.intel.com
  ...
  $ head m/20260203_liusizhe5_pci_fix_pci_bridge_resource_allocation_when_base_exceeds_limit.mbx
  From git@z Thu Jan  1 00:00:00 1970
  Subject: [PATCH] PCI: Fix PCI bridge resource allocation when base exceeds
   limit
  From: Sizhe Liu <liusizhe5@huawei.com>
  Date: Tue, 03 Feb 2026 10:35:45 +0800
  ...

> ---
>  drivers/pci/setup-bus.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
> index 6e90f46f52af..43ea635e1ea8 100644
> --- a/drivers/pci/setup-bus.c
> +++ b/drivers/pci/setup-bus.c
> @@ -1733,6 +1733,8 @@ static void pci_claim_bridge_resources(struct pci_dev *dev)
>  
>  		if (!r->flags || r->parent)
>  			continue;
> +		if (r->flags & IORESOURCE_DISABLED)
> +			continue;
>  
>  		pci_claim_bridge_resource(dev, i);
>  	}
> 
> base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
> -- 
> 2.39.5


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

end of thread, other threads:[~2026-02-06 22:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-03  2:35 [PATCH] PCI: Fix PCI bridge resource allocation when base exceeds limit Sizhe Liu
2026-02-03 15:14 ` Ilpo Järvinen
2026-02-03 17:21   ` Ilpo Järvinen
2026-02-04  8:56     ` Sizhe LIU
2026-02-06 22:17     ` Bjorn Helgaas
2026-02-04  3:58   ` Sizhe LIU

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