diff options
| author | Ray Jui <ray.jui@broadcom.com> | 2018-01-11 15:36:16 -0500 |
|---|---|---|
| committer | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | 2018-01-12 05:40:18 -0500 |
| commit | 3b65ca50d24ce33cb92d88840e289135c92b40ed (patch) | |
| tree | b2b17d3f2c817ebcf7ac146026b27b69b61f6370 | |
| parent | 09b2d20349e37a03a0951ab69524b516c8f1cc5b (diff) | |
PCI: iproc: Fix NULL pointer dereference for BCMA
With the inbound DMA mapping supported added, the iProc PCIe driver
parses DT property "dma-ranges" through call to
"of_pci_dma_range_parser_init()". In the case of BCMA, this results in a
NULL pointer deference due to a missing of_node.
Fix this by adding a guard in pcie-iproc-platform.c to only enable the
inbound DMA mapping logic when DT property "dma-ranges" is present.
Fixes: dd9d4e7498de3 ("PCI: iproc: Add inbound DMA mapping support")
Reported-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Ray Jui <ray.jui@broadcom.com>
[lorenzo.pieralisi@arm.com: updated commit log]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Tested-by: Rafał Miłecki <rafal@milecki.pl>
cc: <stable@vger.kernel.org> # 4.10+
| -rw-r--r-- | drivers/pci/host/pcie-iproc-platform.c | 7 | ||||
| -rw-r--r-- | drivers/pci/host/pcie-iproc.c | 8 | ||||
| -rw-r--r-- | drivers/pci/host/pcie-iproc.h | 2 |
3 files changed, 14 insertions, 3 deletions
diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c index a5073a921a04..32228d41f746 100644 --- a/drivers/pci/host/pcie-iproc-platform.c +++ b/drivers/pci/host/pcie-iproc-platform.c | |||
| @@ -92,6 +92,13 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev) | |||
| 92 | pcie->need_ob_cfg = true; | 92 | pcie->need_ob_cfg = true; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | /* | ||
| 96 | * DT nodes are not used by all platforms that use the iProc PCIe | ||
| 97 | * core driver. For platforms that require explict inbound mapping | ||
| 98 | * configuration, "dma-ranges" would have been present in DT | ||
| 99 | */ | ||
| 100 | pcie->need_ib_cfg = of_property_read_bool(np, "dma-ranges"); | ||
| 101 | |||
| 95 | /* PHY use is optional */ | 102 | /* PHY use is optional */ |
| 96 | pcie->phy = devm_phy_get(dev, "pcie-phy"); | 103 | pcie->phy = devm_phy_get(dev, "pcie-phy"); |
| 97 | if (IS_ERR(pcie->phy)) { | 104 | if (IS_ERR(pcie->phy)) { |
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c index 935909bbe5c4..75836067f538 100644 --- a/drivers/pci/host/pcie-iproc.c +++ b/drivers/pci/host/pcie-iproc.c | |||
| @@ -1378,9 +1378,11 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) | |||
| 1378 | } | 1378 | } |
| 1379 | } | 1379 | } |
| 1380 | 1380 | ||
| 1381 | ret = iproc_pcie_map_dma_ranges(pcie); | 1381 | if (pcie->need_ib_cfg) { |
| 1382 | if (ret && ret != -ENOENT) | 1382 | ret = iproc_pcie_map_dma_ranges(pcie); |
| 1383 | goto err_power_off_phy; | 1383 | if (ret && ret != -ENOENT) |
| 1384 | goto err_power_off_phy; | ||
| 1385 | } | ||
| 1384 | 1386 | ||
| 1385 | #ifdef CONFIG_ARM | 1387 | #ifdef CONFIG_ARM |
| 1386 | pcie->sysdata.private_data = pcie; | 1388 | pcie->sysdata.private_data = pcie; |
diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h index a6b55cec9a66..4ac6282f2bfd 100644 --- a/drivers/pci/host/pcie-iproc.h +++ b/drivers/pci/host/pcie-iproc.h | |||
| @@ -74,6 +74,7 @@ struct iproc_msi; | |||
| 74 | * @ob: outbound mapping related parameters | 74 | * @ob: outbound mapping related parameters |
| 75 | * @ob_map: outbound mapping related parameters specific to the controller | 75 | * @ob_map: outbound mapping related parameters specific to the controller |
| 76 | * | 76 | * |
| 77 | * @need_ib_cfg: indicates SW needs to configure the inbound mapping window | ||
| 77 | * @ib: inbound mapping related parameters | 78 | * @ib: inbound mapping related parameters |
| 78 | * @ib_map: outbound mapping region related parameters | 79 | * @ib_map: outbound mapping region related parameters |
| 79 | * | 80 | * |
| @@ -101,6 +102,7 @@ struct iproc_pcie { | |||
| 101 | struct iproc_pcie_ob ob; | 102 | struct iproc_pcie_ob ob; |
| 102 | const struct iproc_pcie_ob_map *ob_map; | 103 | const struct iproc_pcie_ob_map *ob_map; |
| 103 | 104 | ||
| 105 | bool need_ib_cfg; | ||
| 104 | struct iproc_pcie_ib ib; | 106 | struct iproc_pcie_ib ib; |
| 105 | const struct iproc_pcie_ib_map *ib_map; | 107 | const struct iproc_pcie_ib_map *ib_map; |
| 106 | 108 | ||
