* FAILED: patch "[PATCH] PCI: Fix BAR resize for devices on a root bus" failed to apply to 6.6-stable tree
@ 2026-09-29 8:28 gregkh
2026-09-30 0:20 ` [PATCH 6.6.y 1/2] PCI: Fix Resizable BAR restore order Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: gregkh @ 2026-09-29 8:28 UTC (permalink / raw)
To: lizf, bhelgaas, ilpo.jarvinen; +Cc: stable
The patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x d58384c22739848efe14b34e9586e4f1242f33c0
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026092923-escalator-elephant-9055@gregkh' --subject-prefix 'PATCH 6.6.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d58384c22739848efe14b34e9586e4f1242f33c0 Mon Sep 17 00:00:00 2001
From: Liz Fong-Jones <lizf@honeycomb.io>
Date: Fri, 18 Sep 2026 03:56:33 +0000
Subject: [PATCH] PCI: Fix BAR resize for devices on a root bus
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
pci_do_resource_release_and_resize() releases device BARs that share a
bridge window with the BAR being resized, but when the device sits directly
on a root bus (pdev->bus->self == NULL) it then skips resource assignment
entirely and returns success, leaving the BARs it just released unassigned
(IORESOURCE_UNSET).
Skipping pbus_reassign_bridge_resources() is correct in that case -- there
is no bridge window to adjust -- but the device BARs still have to be
reassigned. Before the BAR release was consolidated into the PCI core, this
case worked for amdgpu because the driver released the BARs itself and then
called pci_assign_unassigned_bus_resources() unconditionally after the
resize, which assigns unassigned device BARs also on a root bus. Commit
db92e3fef53e ("drm/amdgpu: Remove driver side BAR release before resize")
removed that call, so nothing assigns the released BARs anymore.
This breaks amdgpu completely on the SolidRun HoneyComb LX2K (NXP LX2160A,
arm64, ACPI), where ACPI doesn't expose the Root Port so the GPU endpoint
appears directly on a "root bus" of its segment:
amdgpu 0004:01:00.0: BAR 0 [mem 0xa400000000-0xa40fffffff 64bit pref]: releasing
amdgpu 0004:01:00.0: BAR 2 [mem 0xa410000000-0xa4101fffff 64bit pref]: releasing
amdgpu 0004:01:00.0: sw_init of IP block <gmc_v8_0> failed -19
amdgpu 0004:01:00.0: amdgpu_device_ip_init failed
amdgpu 0004:01:00.0: Fatal error during GPU init
No error is logged because the resize path reports success; amdgpu then
finds BAR 0 IORESOURCE_UNSET and bails out with -ENODEV.
When there is no upstream bridge, call pci_bus_assign_resources() on the
root bus to place the BARs released above, using the same alignment-sorted
algorithm as normal enumeration instead of a manual per-BAR loop. This also
walks the rest of the hierarchy under the root bus, as
pci_assign_unassigned_bus_resources() used to for amdgpu before commit
db92e3fef53e ("drm/amdgpu: Remove driver side BAR release before resize")
removed that call -- the core-side fix that commit asked for ("such a
problem should be fixed inside pci_resize_resource() instead").
pci_bus_assign_resources() returns void, so failure is detected by checking
whether the released BARs are still assigned afterward; if not, roll back
as in the bridged case. This is stricter than the bridged path -- it fails
on any unplaced resource, not just required ones -- since a root bus
typically has one shared window, and failing loudly seemed better than
leaving something silently unassigned.
The root bus path also had a locking bug that any fix here necessarily
touches: the old "goto out" jumped to up_read(&pci_bus_sem) without a
matching down_read() (as does the "goto restore" taken when
pci_dev_res_add_to_list() fails in the release loop). Take pci_bus_sem
before the BAR release loop so every path through the function holds it
exactly once.
Fixes: 337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path")
Link: https://bugs.launchpad.net/ubuntu/+source/linux-hwe-7.0/+bug/2159596
Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Assisted-by: Claude:claude-fable-5 checkpatch
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Liz Fong-Jones <lizf@honeycomb.io>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260918035633.566823-1-lizf@honeycomb.io
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index e8c94aa1d3c1..ed16ef7c26fa 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -2380,6 +2380,7 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size
struct resource *res = pci_resource_n(pdev, resno);
struct pci_dev_resource *dev_res;
struct pci_bus *bus = pdev->bus;
+ struct pci_dev *bridge = pci_upstream_bridge(pdev);
struct resource *b_win, *r;
LIST_HEAD(saved);
unsigned int i;
@@ -2397,6 +2398,8 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size
if (ret)
return ret;
+ down_read(&pci_bus_sem);
+
pci_dev_for_each_resource(pdev, r, i) {
if (i >= PCI_BRIDGE_RESOURCES)
break;
@@ -2415,13 +2418,21 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size
pci_resize_resource_set_size(pdev, resno, size);
- if (!bus->self)
- goto out;
+ if (bridge) {
+ ret = pbus_reassign_bridge_resources(bus, res, &saved);
+ if (ret)
+ goto restore;
+ } else {
+ /* No bridge window to adjust; let the core reassign the bus. */
+ pci_bus_assign_resources(bus);
- down_read(&pci_bus_sem);
- ret = pbus_reassign_bridge_resources(bus, res, &saved);
- if (ret)
- goto restore;
+ list_for_each_entry(dev_res, &saved, list) {
+ if (!resource_assigned(dev_res->res)) {
+ ret = -ENOSPC;
+ goto restore;
+ }
+ }
+ }
out:
up_read(&pci_bus_sem);
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 6.6.y 1/2] PCI: Fix Resizable BAR restore order 2026-09-29 8:28 FAILED: patch "[PATCH] PCI: Fix BAR resize for devices on a root bus" failed to apply to 6.6-stable tree gregkh @ 2026-09-30 0:20 ` Sasha Levin 2026-09-30 0:20 ` [PATCH 6.6.y 2/2] PCI: Fix BAR resize for devices on a root bus Sasha Levin 0 siblings, 1 reply; 3+ messages in thread From: Sasha Levin @ 2026-09-30 0:20 UTC (permalink / raw) To: stable Cc: Ilpo Järvinen, Ville Syrjälä, Bjorn Helgaas, Sasha Levin From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> [ Upstream commit 5528fd38f230c906fcebb202cc94fbb8ed8f122a ] The commit 337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path") changed BAR resize to layer rebar code and resource setup/restore code cleanly. Unfortunately, it did not consider how the value of the BAR Size field impacts the read-only bits in the Base Address Register (PCIe7 spec, sec. 7.8.6.3). That is, it very much matters in which order the BAR Size and Base Address Register are restored. Post-337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path") during BAR resize rollback, pci_do_resource_release_and_resize() attempts to restore the old address to the BAR that was resized, but it can fail to setup the address correctly if the address has low bits set that collide with the bits that are still read-only. As a result, kernel's resource and BAR will be out-of-sync. Fix this by restoring BAR Size before rolling back the resource changes and restoring the BAR. Fixes: 337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path") Reported-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://lore.kernel.org/linux-pci/aW_w1oFQCzUxGYtu@intel.com/ Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Tested-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260121131417.9582-3-ilpo.jarvinen@linux.intel.com [6.12 dependency preparation for d58384c22739848efe14b34e9586e4f1242f33c0: Keep the existing memory-decoding and supported-size checks in rebar.c. Move BAR size programming and rollback into the resource release helper, so the old size is restored before restoring BAR addresses. Use the assigned parent window to select resources for release, retaining the old flags-based selection when the resized BAR has no parent. Provide file-local macro mappings for the follow-up's bridge reassignment and resource assignment checks; no functions are added. Retain the upstream pre-target pci_bus_sem placement to allow the target to apply without conflicts. This preparatory dependency must be applied together with d58384c22739848efe14b34e9586e4f1242f33c0, which takes the lock before releasing resources and assigns released BARs on root buses.] Stable-dep-of: d58384c22739 ("PCI: Fix BAR resize for devices on a root bus") Signed-off-by: Sasha Levin <sashal@kernel.org> --- drivers/pci/rebar.c | 19 +------------------ drivers/pci/setup-bus.c | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/drivers/pci/rebar.c b/drivers/pci/rebar.c index 920ef3ab4bda3..d5e432d084e51 100644 --- a/drivers/pci/rebar.c +++ b/drivers/pci/rebar.c @@ -177,7 +177,6 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size, int exclude_bars) { struct pci_host_bridge *host; - int old, ret; u32 sizes; u16 cmd; @@ -197,22 +196,6 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size, if (!(sizes & BIT(size))) return -EINVAL; - old = pci_rebar_get_current_size(dev, resno); - if (old < 0) - return old; - - ret = pci_rebar_set_size(dev, resno, size); - if (ret) - return ret; - - ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars); - if (ret) - goto error_resize; - - return 0; - -error_resize: - pci_rebar_set_size(dev, resno, old); - return ret; + return pci_do_resource_release_and_resize(dev, resno, size, exclude_bars); } EXPORT_SYMBOL(pci_resize_resource); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 98d0038e32ef9..fc752f5ef3f8d 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -2292,6 +2292,11 @@ static int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long t return 0; } +/* Keep the resize follow-up compatible with the 6.12 resource helpers. */ +#define pbus_reassign_bridge_resources(bus, res, saved) \ + pci_reassign_bridge_resources((bus)->self, (res)->flags, (saved)) +#define resource_assigned(res) ((res)->parent != NULL) + int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size, int exclude_bars) { @@ -2299,12 +2304,20 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size unsigned long flags = res->flags; struct pci_dev_resource *dev_res; struct pci_bus *bus = pdev->bus; - struct resource *r; + struct resource *b_win, *r; LIST_HEAD(saved); unsigned int i; - int ret = 0; + int old, ret; - down_read(&pci_bus_sem); + b_win = res->parent; + + old = pci_rebar_get_current_size(pdev, resno); + if (old < 0) + return old; + + ret = pci_rebar_set_size(pdev, resno, size); + if (ret) + return ret; pci_dev_for_each_resource(pdev, r, i) { if (i >= PCI_BRIDGE_RESOURCES) @@ -2313,7 +2326,10 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size if (exclude_bars & BIT(i)) continue; - if (!pci_resource_len(pdev, i) || r->flags != flags) + if (!pci_resource_len(pdev, i)) + continue; + + if (b_win ? r->parent != b_win : r->flags != flags) continue; ret = add_to_list(&saved, pdev, r, 0, 0); @@ -2327,7 +2343,8 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size if (!bus->self) goto out; - ret = pci_reassign_bridge_resources(bus->self, res->flags, &saved); + down_read(&pci_bus_sem); + ret = pbus_reassign_bridge_resources(bus, res, &saved); if (ret) goto restore; @@ -2337,14 +2354,22 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size return ret; restore: - /* Revert to the old configuration */ + /* + * Revert to the old configuration. + * + * BAR Size must be restored first because it affects the read-only + * bits in BAR (the old address might not be restorable otherwise + * due to low address bits). + */ + pci_rebar_set_size(pdev, resno, old); + list_for_each_entry(dev_res, &saved, list) { struct resource *res = dev_res->res; struct pci_dev *dev = dev_res->dev; i = res - dev->resource; - if (res->parent) { + if (resource_assigned(res)) { release_child_resources(res); pci_release_resource(dev, i); } -- 2.53.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 6.6.y 2/2] PCI: Fix BAR resize for devices on a root bus 2026-09-30 0:20 ` [PATCH 6.6.y 1/2] PCI: Fix Resizable BAR restore order Sasha Levin @ 2026-09-30 0:20 ` Sasha Levin 0 siblings, 0 replies; 3+ messages in thread From: Sasha Levin @ 2026-09-30 0:20 UTC (permalink / raw) To: stable; +Cc: Liz Fong-Jones, Ilpo Järvinen, Bjorn Helgaas, Sasha Levin From: Liz Fong-Jones <lizf@honeycomb.io> [ Upstream commit d58384c22739848efe14b34e9586e4f1242f33c0 ] pci_do_resource_release_and_resize() releases device BARs that share a bridge window with the BAR being resized, but when the device sits directly on a root bus (pdev->bus->self == NULL) it then skips resource assignment entirely and returns success, leaving the BARs it just released unassigned (IORESOURCE_UNSET). Skipping pbus_reassign_bridge_resources() is correct in that case -- there is no bridge window to adjust -- but the device BARs still have to be reassigned. Before the BAR release was consolidated into the PCI core, this case worked for amdgpu because the driver released the BARs itself and then called pci_assign_unassigned_bus_resources() unconditionally after the resize, which assigns unassigned device BARs also on a root bus. Commit db92e3fef53e ("drm/amdgpu: Remove driver side BAR release before resize") removed that call, so nothing assigns the released BARs anymore. This breaks amdgpu completely on the SolidRun HoneyComb LX2K (NXP LX2160A, arm64, ACPI), where ACPI doesn't expose the Root Port so the GPU endpoint appears directly on a "root bus" of its segment: amdgpu 0004:01:00.0: BAR 0 [mem 0xa400000000-0xa40fffffff 64bit pref]: releasing amdgpu 0004:01:00.0: BAR 2 [mem 0xa410000000-0xa4101fffff 64bit pref]: releasing amdgpu 0004:01:00.0: sw_init of IP block <gmc_v8_0> failed -19 amdgpu 0004:01:00.0: amdgpu_device_ip_init failed amdgpu 0004:01:00.0: Fatal error during GPU init No error is logged because the resize path reports success; amdgpu then finds BAR 0 IORESOURCE_UNSET and bails out with -ENODEV. When there is no upstream bridge, call pci_bus_assign_resources() on the root bus to place the BARs released above, using the same alignment-sorted algorithm as normal enumeration instead of a manual per-BAR loop. This also walks the rest of the hierarchy under the root bus, as pci_assign_unassigned_bus_resources() used to for amdgpu before commit db92e3fef53e ("drm/amdgpu: Remove driver side BAR release before resize") removed that call -- the core-side fix that commit asked for ("such a problem should be fixed inside pci_resize_resource() instead"). pci_bus_assign_resources() returns void, so failure is detected by checking whether the released BARs are still assigned afterward; if not, roll back as in the bridged case. This is stricter than the bridged path -- it fails on any unplaced resource, not just required ones -- since a root bus typically has one shared window, and failing loudly seemed better than leaving something silently unassigned. The root bus path also had a locking bug that any fix here necessarily touches: the old "goto out" jumped to up_read(&pci_bus_sem) without a matching down_read() (as does the "goto restore" taken when pci_dev_res_add_to_list() fails in the release loop). Take pci_bus_sem before the BAR release loop so every path through the function holds it exactly once. Fixes: 337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path") Link: https://bugs.launchpad.net/ubuntu/+source/linux-hwe-7.0/+bug/2159596 Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Assisted-by: Claude:claude-fable-5 checkpatch Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Liz Fong-Jones <lizf@honeycomb.io> [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260918035633.566823-1-lizf@honeycomb.io Signed-off-by: Sasha Levin <sashal@kernel.org> --- drivers/pci/setup-bus.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index fc752f5ef3f8d..df39fa8529979 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -2304,6 +2304,7 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size unsigned long flags = res->flags; struct pci_dev_resource *dev_res; struct pci_bus *bus = pdev->bus; + struct pci_dev *bridge = pci_upstream_bridge(pdev); struct resource *b_win, *r; LIST_HEAD(saved); unsigned int i; @@ -2319,6 +2320,8 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size if (ret) return ret; + down_read(&pci_bus_sem); + pci_dev_for_each_resource(pdev, r, i) { if (i >= PCI_BRIDGE_RESOURCES) break; @@ -2340,13 +2343,21 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size res->end = res->start + pci_rebar_size_to_bytes(size) - 1; - if (!bus->self) - goto out; + if (bridge) { + ret = pbus_reassign_bridge_resources(bus, res, &saved); + if (ret) + goto restore; + } else { + /* No bridge window to adjust; let the core reassign the bus. */ + pci_bus_assign_resources(bus); - down_read(&pci_bus_sem); - ret = pbus_reassign_bridge_resources(bus, res, &saved); - if (ret) - goto restore; + list_for_each_entry(dev_res, &saved, list) { + if (!resource_assigned(dev_res->res)) { + ret = -ENOSPC; + goto restore; + } + } + } out: up_read(&pci_bus_sem); -- 2.53.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-30 0:20 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-29 8:28 FAILED: patch "[PATCH] PCI: Fix BAR resize for devices on a root bus" failed to apply to 6.6-stable tree gregkh 2026-09-30 0:20 ` [PATCH 6.6.y 1/2] PCI: Fix Resizable BAR restore order Sasha Levin 2026-09-30 0:20 ` [PATCH 6.6.y 2/2] PCI: Fix BAR resize for devices on a root bus Sasha Levin
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.