| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 | 
							- From 6e347b5e05ea2ac4ac467a5a1cfaebb2c7f06f80 Mon Sep 17 00:00:00 2001
 
- From: Bjorn Helgaas <[email protected]>
 
- Date: Thu, 9 Mar 2017 11:27:07 -0600
 
- Subject: [PATCH] PCI: iproc: Save host bridge window resource in struct
 
-  iproc_pcie
 
- MIME-Version: 1.0
 
- Content-Type: text/plain; charset=UTF-8
 
- Content-Transfer-Encoding: 8bit
 
- The host bridge memory window resource is inserted into the iomem_resource
 
- tree and cannot be deallocated until the host bridge itself is removed.
 
- Previously, the window was on the stack, which meant the iomem_resource
 
- entry pointed into the stack and was corrupted as soon as the probe
 
- function returned, which caused memory corruption and errors like this:
 
-   pcie_iproc_bcma bcma0:8: resource collision: [mem 0x40000000-0x47ffffff] conflicts with PCIe MEM space [mem 0x40000000-0x47ffffff]
 
- Move the memory window resource from the stack into struct iproc_pcie so
 
- its lifetime matches that of the host bridge.
 
- Fixes: c3245a566400 ("PCI: iproc: Request host bridge window resources")
 
- Reported-and-tested-by: Rafał Miłecki <[email protected]>
 
- Signed-off-by: Bjorn Helgaas <[email protected]>
 
- CC: [email protected]	# v4.8+
 
- ---
 
-  drivers/pci/host/pcie-iproc-bcma.c     | 24 ++++++++++++------------
 
-  drivers/pci/host/pcie-iproc-platform.c | 19 ++++++++++---------
 
-  drivers/pci/host/pcie-iproc.h          |  1 +
 
-  3 files changed, 23 insertions(+), 21 deletions(-)
 
- --- a/drivers/pci/host/pcie-iproc-bcma.c
 
- +++ b/drivers/pci/host/pcie-iproc-bcma.c
 
- @@ -44,8 +44,7 @@ static int iproc_pcie_bcma_probe(struct
 
-  {
 
-  	struct device *dev = &bdev->dev;
 
-  	struct iproc_pcie *pcie;
 
- -	LIST_HEAD(res);
 
- -	struct resource res_mem;
 
- +	LIST_HEAD(resources);
 
-  	int ret;
 
-  
 
-  	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
 
- @@ -62,22 +61,23 @@ static int iproc_pcie_bcma_probe(struct
 
-  
 
-  	pcie->base_addr = bdev->addr;
 
-  
 
- -	res_mem.start = bdev->addr_s[0];
 
- -	res_mem.end = bdev->addr_s[0] + SZ_128M - 1;
 
- -	res_mem.name = "PCIe MEM space";
 
- -	res_mem.flags = IORESOURCE_MEM;
 
- -	pci_add_resource(&res, &res_mem);
 
- +	pcie->mem.start = bdev->addr_s[0];
 
- +	pcie->mem.end = bdev->addr_s[0] + SZ_128M - 1;
 
- +	pcie->mem.name = "PCIe MEM space";
 
- +	pcie->mem.flags = IORESOURCE_MEM;
 
- +	pci_add_resource(&resources, &pcie->mem);
 
-  
 
-  	pcie->map_irq = iproc_pcie_bcma_map_irq;
 
-  
 
- -	ret = iproc_pcie_setup(pcie, &res);
 
- -	if (ret)
 
- +	ret = iproc_pcie_setup(pcie, &resources);
 
- +	if (ret) {
 
-  		dev_err(dev, "PCIe controller setup failed\n");
 
- -
 
- -	pci_free_resource_list(&res);
 
- +		pci_free_resource_list(&resources);
 
- +		return ret;
 
- +	}
 
-  
 
-  	bcma_set_drvdata(bdev, pcie);
 
- -	return ret;
 
- +	return 0;
 
-  }
 
-  
 
-  static void iproc_pcie_bcma_remove(struct bcma_device *bdev)
 
- --- a/drivers/pci/host/pcie-iproc-platform.c
 
- +++ b/drivers/pci/host/pcie-iproc-platform.c
 
- @@ -46,7 +46,7 @@ static int iproc_pcie_pltfm_probe(struct
 
-  	struct device_node *np = dev->of_node;
 
-  	struct resource reg;
 
-  	resource_size_t iobase = 0;
 
- -	LIST_HEAD(res);
 
- +	LIST_HEAD(resources);
 
-  	int ret;
 
-  
 
-  	of_id = of_match_device(iproc_pcie_of_match_table, dev);
 
- @@ -108,23 +108,24 @@ static int iproc_pcie_pltfm_probe(struct
 
-  		pcie->phy = NULL;
 
-  	}
 
-  
 
- -	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase);
 
- +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &resources,
 
- +					       &iobase);
 
-  	if (ret) {
 
- -		dev_err(dev,
 
- -			"unable to get PCI host bridge resources\n");
 
- +		dev_err(dev, "unable to get PCI host bridge resources\n");
 
-  		return ret;
 
-  	}
 
-  
 
-  	pcie->map_irq = of_irq_parse_and_map_pci;
 
-  
 
- -	ret = iproc_pcie_setup(pcie, &res);
 
- -	if (ret)
 
- +	ret = iproc_pcie_setup(pcie, &resources);
 
- +	if (ret) {
 
-  		dev_err(dev, "PCIe controller setup failed\n");
 
- -
 
- -	pci_free_resource_list(&res);
 
- +		pci_free_resource_list(&resources);
 
- +		return ret;
 
- +	}
 
-  
 
-  	platform_set_drvdata(pdev, pcie);
 
- -	return ret;
 
- +	return 0;
 
-  }
 
-  
 
-  static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
 
- --- a/drivers/pci/host/pcie-iproc.h
 
- +++ b/drivers/pci/host/pcie-iproc.h
 
- @@ -68,6 +68,7 @@ struct iproc_pcie {
 
-  #ifdef CONFIG_ARM
 
-  	struct pci_sys_data sysdata;
 
-  #endif
 
- +	struct resource mem;
 
-  	struct pci_bus *root_bus;
 
-  	struct phy *phy;
 
-  	int (*map_irq)(const struct pci_dev *, u8, u8);
 
 
  |