bcm53xx: use upstream fix for iproc regression
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
		| @@ -0,0 +1,131 @@ | |||||||
|  | From 6e347b5e05ea2ac4ac467a5a1cfaebb2c7f06f80 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Bjorn Helgaas <bhelgaas@google.com> | ||||||
|  | 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 <zajec5@gmail.com> | ||||||
|  | Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> | ||||||
|  | CC: stable@vger.kernel.org	# 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); | ||||||
| @@ -1,28 +0,0 @@ | |||||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> |  | ||||||
| Date: Thu, 9 Mar 2017 10:53:06 +0100 |  | ||||||
| Subject: [PATCH] Revert "PCI: iproc: Request host bridge window resources" |  | ||||||
| MIME-Version: 1.0 |  | ||||||
| Content-Type: text/plain; charset=UTF-8 |  | ||||||
| Content-Transfer-Encoding: 8bit |  | ||||||
|  |  | ||||||
| This reverts commit c3245a566400 ("PCI: iproc: Request host bridge |  | ||||||
| window resources"). It was passing local variable of |  | ||||||
| iproc_pcie_bcma_probe to the devm_request_pci_bus_resources. It meant |  | ||||||
| using unallocated memory for tracing resource which could easily result |  | ||||||
| in corruption and crashes. |  | ||||||
|  |  | ||||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> |  | ||||||
| --- |  | ||||||
|  |  | ||||||
| --- a/drivers/pci/host/pcie-iproc.c |  | ||||||
| +++ b/drivers/pci/host/pcie-iproc.c |  | ||||||
| @@ -462,9 +462,6 @@ int iproc_pcie_setup(struct iproc_pcie * |  | ||||||
|  	struct pci_bus *bus; |  | ||||||
|   |  | ||||||
|  	dev = pcie->dev; |  | ||||||
| -	ret = devm_request_pci_bus_resources(dev, res); |  | ||||||
| -	if (ret) |  | ||||||
| -		return ret; |  | ||||||
|   |  | ||||||
|  	ret = phy_init(pcie->phy); |  | ||||||
|  	if (ret) { |  | ||||||
		Reference in New Issue
	
	Block a user
	 Rafał Miłecki
					Rafał Miłecki