summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoss Lagerwall <ross.lagerwall@citrix.com>2023-05-25 16:32:48 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-05-02 07:44:40 +0200
commit26277a4250207e630c9a11f4ead4ef6e8441bf1f (patch)
treeb4e455ae9643b44ac63551d8a617d5bc1e63af32
parente4af080f3ef6a65b0d702988c2471a47c9ae2cc0 (diff)
PCI: Release resource invalidated by coalescing
commit e54223275ba1bc6f704a6bab015fcd2ae4f72572 upstream. When contiguous windows are coalesced by pci_register_host_bridge(), the second resource is expanded to include the first, and the first is invalidated and consequently not added to the bus. However, it remains in the resource hierarchy. For example, these windows: fec00000-fec7ffff : PCI Bus 0000:00 fec80000-fecbffff : PCI Bus 0000:00 are coalesced into this, where the first resource remains in the tree with start/end zeroed out: 00000000-00000000 : PCI Bus 0000:00 fec00000-fecbffff : PCI Bus 0000:00 In some cases (e.g. the Xen scratch region), this causes future calls to allocate_resource() to choose an inappropriate location which the caller cannot handle. Fix by releasing the zeroed-out resource and removing it from the resource hierarchy. [bhelgaas: commit log] Fixes: 7c3855c423b1 ("PCI: Coalesce host bridge contiguous apertures") Link: https://lore.kernel.org/r/20230525153248.712779-1-ross.lagerwall@citrix.com Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Cc: stable@vger.kernel.org # v5.16+ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/pci/probe.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6f9f72a08cd7..773715992cf0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -999,8 +999,10 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
resource_list_for_each_entry_safe(window, n, &resources) {
offset = window->offset;
res = window->res;
- if (!res->flags && !res->start && !res->end)
+ if (!res->flags && !res->start && !res->end) {
+ release_resource(res);
continue;
+ }
list_move_tail(&window->node, &bridge->windows);