summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2016-08-15 17:50:46 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-10-31 05:02:15 -0600
commit10a12e89de35ed6aa94b5b2002e887a9c867547d (patch)
tree1bfc089125b99db381f041b5be82786ee836f2bf
parent12d904f4dbe29384f573fa4f422bf68b0e0c80e9 (diff)
PCI: tegra: Fix pci_remap_iospace() failure path
commit 13f392ebc37e31568fae72a73ee378ae22a9740f 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 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 tegra host bridge driver adds the PCI IO resource retrieved from firmware to the host bridge resource windows even 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). Add the PCI host bridge driver pci_remap_iospace() failure path and do not add the corresponding PCI host bridge PCI IO resources retrieved through firmware when the pci_remap_iospace() function call fails, fixing the issue. Fixes: e6e9f471f5fe ("PCI: tegra: Use generic pci_remap_iospace() rather than ARM32-specific one") Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> CC: Thierry Reding <treding@nvidia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/pci/host/pci-tegra.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 84d650d892e7..7ec1e800096a 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -621,7 +621,11 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
if (err < 0)
return err;
- pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset);
+ err = pci_remap_iospace(&pcie->pio, pcie->io.start);
+ if (!err)
+ pci_add_resource_offset(&sys->resources, &pcie->pio,
+ sys->io_offset);
+
pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
pci_add_resource_offset(&sys->resources, &pcie->prefetch,
sys->mem_offset);
@@ -631,7 +635,6 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
if (err < 0)
return err;
- pci_remap_iospace(&pcie->pio, pcie->io.start);
return 1;
}