Commit 43219fb6 authored by Yinghai Lu's avatar Yinghai Lu Committed by Luis Henriques

PCI: Add pci_bus_clip_resource() to clip to fit upstream window

commit 0f7e7aee upstream.

Add pci_bus_clip_resource().  If a PCI-PCI bridge window overlaps an
upstream bridge window but is not completely contained by it, this clips
the downstream window so it fits inside the upstream one.

No functional change (this adds the function but no callers).

[bhelgaas: changelog, split into separate patch]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491Reported-by: default avatarMarek Kordik <kordikmarek@gmail.com>
Fixes: 5b285415 ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent f8bf6f71
...@@ -228,6 +228,49 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, ...@@ -228,6 +228,49 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
} }
EXPORT_SYMBOL(pci_bus_alloc_resource); EXPORT_SYMBOL(pci_bus_alloc_resource);
/*
* The @idx resource of @dev should be a PCI-PCI bridge window. If this
* resource fits inside a window of an upstream bridge, do nothing. If it
* overlaps an upstream window but extends outside it, clip the resource so
* it fits completely inside.
*/
bool pci_bus_clip_resource(struct pci_dev *dev, int idx)
{
struct pci_bus *bus = dev->bus;
struct resource *res = &dev->resource[idx];
struct resource orig_res = *res;
struct resource *r;
int i;
pci_bus_for_each_resource(bus, r, i) {
resource_size_t start, end;
if (!r)
continue;
if (resource_type(res) != resource_type(r))
continue;
start = max(r->start, res->start);
end = min(r->end, res->end);
if (start > end)
continue; /* no overlap */
if (res->start == start && res->end == end)
return false; /* no change */
res->start = start;
res->end = end;
dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n",
&orig_res, res);
return true;
}
return false;
}
void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
/** /**
......
...@@ -206,6 +206,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus, ...@@ -206,6 +206,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus,
void __pci_bus_assign_resources(const struct pci_bus *bus, void __pci_bus_assign_resources(const struct pci_bus *bus,
struct list_head *realloc_head, struct list_head *realloc_head,
struct list_head *fail_head); struct list_head *fail_head);
bool pci_bus_clip_resource(struct pci_dev *dev, int idx);
/** /**
* pci_ari_enabled - query ARI forwarding status * pci_ari_enabled - query ARI forwarding status
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment