[PATCH 4.8 120/125] PCI: aardvark: Fix pci_remap_iospace() failure path

From: Greg Kroah-Hartman
Date: Sat Oct 29 2016 - 09:59:45 EST


4.8-stable review patch. If anyone has any objections, please let me know.

------------------

From: Lorenzo Pieralisi <lorenzo.pieralisi@xxxxxxx>

commit db047f8a931275e50563dd79c3d62d977074959a upstream.

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 bridge's 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 aardvark 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: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver")
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@xxxxxxx>
Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
CC: Thomas Petazzoni <thomas.petazzoni@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/pci/host/pci-aardvark.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -848,7 +848,7 @@ static int advk_pcie_parse_request_of_pc
int err, res_valid = 0;
struct device *dev = &pcie->pdev->dev;
struct device_node *np = dev->of_node;
- struct resource_entry *win;
+ struct resource_entry *win, *tmp;
resource_size_t iobase;

INIT_LIST_HEAD(&pcie->resources);
@@ -862,7 +862,7 @@ static int advk_pcie_parse_request_of_pc
if (err)
goto out_release_res;

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

switch (resource_type(res)) {
@@ -874,9 +874,11 @@ static int advk_pcie_parse_request_of_pc
lower_32_bits(res->start),
OB_PCIE_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:
advk_pcie_set_ob_win(pcie, 0,