Skip to content

Commit

Permalink
PCI: generic: Fix pci_remap_iospace() failure path
Browse files Browse the repository at this point in the history
On ARM/ARM64 architectures, PCI IO ports are emulated through memory mapped
IO, by reserving a chunk of virtual address space starting at PCI_IOBASE
and by mapping the PCI host bridges memory address space driving PCI IO
cycles to it.

PCI host bridge drivers that enable downstream PCI IO cycles map the host
bridge memory address responding to PCI IO cycles to the fixed virtual
address space through the pci_remap_iospace() API.

This means that if the pci_remap_iospace() function fails, the
corresponding host bridge PCI IO resource must be considered invalid, in
that there is no way for the kernel to actually drive PCI IO transactions
if the memory addresses responding to PCI IO cycles cannot be mapped into
the CPU virtual address space.

The PCI common host bridge driver does not remove the PCI IO resource from
the host bridge resource windows if the pci_remap_iospace() call fails;
this is an actual bug in that the PCI host bridge would consider the PCI IO
resource valid (and possibly assign it to downstream devices) even if the
kernel was not able to map the PCI host bridge memory address driving IO
cycle to the CPU virtual address space (ie pci_remap_iospace() failures).

Fix the PCI host bridge driver pci_remap_iospace() failure path, by
destroying the PCI host bridge PCI IO resources retrieved through firmware
when the pci_remap_iospace() function call fails, therefore preventing the
kernel from adding the respective PCI IO resource to the list of PCI host
bridge valid resources, fixing the issue.

Fixes: 4e64dbe ("PCI: generic: Expose pci_host_common_probe() for use by other drivers")
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Will Deacon <will.deacon@arm.com>
  • Loading branch information
Lorenzo Pieralisi authored and Bjorn Helgaas committed Sep 6, 2016
1 parent 5e8c873 commit 43281ed
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions drivers/pci/host/pci-host-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ static int gen_pci_parse_request_of_pci_ranges(struct device *dev,
int err, res_valid = 0;
struct device_node *np = dev->of_node;
resource_size_t iobase;
struct resource_entry *win;
struct resource_entry *win, *tmp;

err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase);
if (err)
Expand All @@ -39,15 +39,17 @@ static int gen_pci_parse_request_of_pci_ranges(struct device *dev,
if (err)
return err;

resource_list_for_each_entry(win, resources) {
resource_list_for_each_entry_safe(win, tmp, resources) {
struct resource *res = win->res;

switch (resource_type(res)) {
case IORESOURCE_IO:
err = pci_remap_iospace(res, iobase);
if (err)
if (err) {
dev_warn(dev, "error %d: failed to map resource %pR\n",
err, res);
resource_list_destroy_entry(win);
}
break;
case IORESOURCE_MEM:
res_valid |= !(res->flags & IORESOURCE_PREFETCH);
Expand Down

0 comments on commit 43281ed

Please sign in to comment.