089-PCI-iproc-Save-host-bridge-window-resource-in-struct.patch 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. From 6e347b5e05ea2ac4ac467a5a1cfaebb2c7f06f80 Mon Sep 17 00:00:00 2001
  2. From: Bjorn Helgaas <[email protected]>
  3. Date: Thu, 9 Mar 2017 11:27:07 -0600
  4. Subject: [PATCH] PCI: iproc: Save host bridge window resource in struct
  5. iproc_pcie
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. The host bridge memory window resource is inserted into the iomem_resource
  10. tree and cannot be deallocated until the host bridge itself is removed.
  11. Previously, the window was on the stack, which meant the iomem_resource
  12. entry pointed into the stack and was corrupted as soon as the probe
  13. function returned, which caused memory corruption and errors like this:
  14. pcie_iproc_bcma bcma0:8: resource collision: [mem 0x40000000-0x47ffffff] conflicts with PCIe MEM space [mem 0x40000000-0x47ffffff]
  15. Move the memory window resource from the stack into struct iproc_pcie so
  16. its lifetime matches that of the host bridge.
  17. Fixes: c3245a566400 ("PCI: iproc: Request host bridge window resources")
  18. Reported-and-tested-by: Rafał Miłecki <[email protected]>
  19. Signed-off-by: Bjorn Helgaas <[email protected]>
  20. CC: [email protected] # v4.8+
  21. ---
  22. drivers/pci/host/pcie-iproc-bcma.c | 24 ++++++++++++------------
  23. drivers/pci/host/pcie-iproc-platform.c | 19 ++++++++++---------
  24. drivers/pci/host/pcie-iproc.h | 1 +
  25. 3 files changed, 23 insertions(+), 21 deletions(-)
  26. --- a/drivers/pci/host/pcie-iproc-bcma.c
  27. +++ b/drivers/pci/host/pcie-iproc-bcma.c
  28. @@ -44,8 +44,7 @@ static int iproc_pcie_bcma_probe(struct
  29. {
  30. struct device *dev = &bdev->dev;
  31. struct iproc_pcie *pcie;
  32. - LIST_HEAD(res);
  33. - struct resource res_mem;
  34. + LIST_HEAD(resources);
  35. int ret;
  36. pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
  37. @@ -62,22 +61,23 @@ static int iproc_pcie_bcma_probe(struct
  38. pcie->base_addr = bdev->addr;
  39. - res_mem.start = bdev->addr_s[0];
  40. - res_mem.end = bdev->addr_s[0] + SZ_128M - 1;
  41. - res_mem.name = "PCIe MEM space";
  42. - res_mem.flags = IORESOURCE_MEM;
  43. - pci_add_resource(&res, &res_mem);
  44. + pcie->mem.start = bdev->addr_s[0];
  45. + pcie->mem.end = bdev->addr_s[0] + SZ_128M - 1;
  46. + pcie->mem.name = "PCIe MEM space";
  47. + pcie->mem.flags = IORESOURCE_MEM;
  48. + pci_add_resource(&resources, &pcie->mem);
  49. pcie->map_irq = iproc_pcie_bcma_map_irq;
  50. - ret = iproc_pcie_setup(pcie, &res);
  51. - if (ret)
  52. + ret = iproc_pcie_setup(pcie, &resources);
  53. + if (ret) {
  54. dev_err(dev, "PCIe controller setup failed\n");
  55. -
  56. - pci_free_resource_list(&res);
  57. + pci_free_resource_list(&resources);
  58. + return ret;
  59. + }
  60. bcma_set_drvdata(bdev, pcie);
  61. - return ret;
  62. + return 0;
  63. }
  64. static void iproc_pcie_bcma_remove(struct bcma_device *bdev)
  65. --- a/drivers/pci/host/pcie-iproc-platform.c
  66. +++ b/drivers/pci/host/pcie-iproc-platform.c
  67. @@ -46,7 +46,7 @@ static int iproc_pcie_pltfm_probe(struct
  68. struct device_node *np = dev->of_node;
  69. struct resource reg;
  70. resource_size_t iobase = 0;
  71. - LIST_HEAD(res);
  72. + LIST_HEAD(resources);
  73. int ret;
  74. of_id = of_match_device(iproc_pcie_of_match_table, dev);
  75. @@ -108,23 +108,24 @@ static int iproc_pcie_pltfm_probe(struct
  76. pcie->phy = NULL;
  77. }
  78. - ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase);
  79. + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &resources,
  80. + &iobase);
  81. if (ret) {
  82. - dev_err(dev,
  83. - "unable to get PCI host bridge resources\n");
  84. + dev_err(dev, "unable to get PCI host bridge resources\n");
  85. return ret;
  86. }
  87. pcie->map_irq = of_irq_parse_and_map_pci;
  88. - ret = iproc_pcie_setup(pcie, &res);
  89. - if (ret)
  90. + ret = iproc_pcie_setup(pcie, &resources);
  91. + if (ret) {
  92. dev_err(dev, "PCIe controller setup failed\n");
  93. -
  94. - pci_free_resource_list(&res);
  95. + pci_free_resource_list(&resources);
  96. + return ret;
  97. + }
  98. platform_set_drvdata(pdev, pcie);
  99. - return ret;
  100. + return 0;
  101. }
  102. static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
  103. --- a/drivers/pci/host/pcie-iproc.h
  104. +++ b/drivers/pci/host/pcie-iproc.h
  105. @@ -68,6 +68,7 @@ struct iproc_pcie {
  106. #ifdef CONFIG_ARM
  107. struct pci_sys_data sysdata;
  108. #endif
  109. + struct resource mem;
  110. struct pci_bus *root_bus;
  111. struct phy *phy;
  112. int (*map_irq)(const struct pci_dev *, u8, u8);