From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 91F2025B099 for ; Wed, 30 Sep 2026 00:20:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790727624; cv=none; b=WhCOUlSwfh9Z9IwuliD84iP/einzd304mCYiyyGMsvQ6BHPsre1yxHx5Y+0Jr8OPtYckn4SfqasD8hga5GfvE1mwtVJm7s3ZMhM+WURG4QpXT07wUS/2qfJ03Bs3xqqMpZG8YihJrR8jizlX3cwzq+lxDFmfbzJNSQRbcVJ+sRg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790727624; c=relaxed/simple; bh=7Li2RB0Mn3nIbQm729bZFyL+ALw2VWs6580QDRmkhPM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=L9dsPw71OrCewLFB+5VtjBKBvDqRQlBwPchQeDr2YGn4/579Coyw6pXKu3fgl8Opkj4th36he/Dwt7nRrT5RQYnpwc4CJSM+6NyOxEuxdM7h3O9N+t4eMo+x1HXVdjDwG91a/u18ornklMwUhdEI1YtvrcL6faQt0dQT3ib0+2Q= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=noKHQOJL; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="noKHQOJL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C3C771F0089A; Wed, 30 Sep 2026 00:20:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1790727623; bh=f7HH2mvGVzgGN+GZZ6O51zZ3hjJ6kecb7uWIMxGMOU4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=noKHQOJLE1Ph0Z5+DYZcYfKCZE6E7DBrrc/R3Bd3HVTcNEK05neH81Z5sMo0W9zJ7 ePuWT9Vmb3XEQ90TsQXMUspen1J3DNqUUtWGGId3QJ+sYcBokzG0wJpCEqBlWWpuJw pJ6vEbUbgYqCS6y66Kr+mrjCfPdhiHyXnWUSltAqRNU6AlENohtiSvVBU7AG8kbvWv 2mk+S3Ja5Sw7lbXWZtaI6oRwS7MJyBmFwRO4eNLiYdO2bIB+d5PzA4N3zO6+ZAp6bA eeoUacFgIKAAJ95rI2RMOl8nDmV08F6zGlLsVmbWFvOyYUe3SvVyvJ/aU+tYfShfqH kRqQ2N0YpiSPw== From: Sasha Levin To: stable@vger.kernel.org Cc: Liz Fong-Jones , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Bjorn Helgaas , Sasha Levin Subject: [PATCH 6.6.y 2/2] PCI: Fix BAR resize for devices on a root bus Date: Tue, 29 Sep 2026 20:20:20 -0400 Message-ID: <20260930002020.2934016-2-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260930002020.2934016-1-sashal@kernel.org> References: <2026092923-escalator-elephant-9055@gregkh> <20260930002020.2934016-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Liz Fong-Jones [ 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 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 Assisted-by: Claude:claude-fable-5 checkpatch Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Liz Fong-Jones [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas Reviewed-by: Ilpo Järvinen Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260918035633.566823-1-lizf@honeycomb.io Signed-off-by: Sasha Levin --- 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