]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.67/pci-of-fix-i-o-space-page-leak.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.14.67 / pci-of-fix-i-o-space-page-leak.patch
1 From a5fb9fb023a1435f2b42bccd7f547560f3a21dc3 Mon Sep 17 00:00:00 2001
2 From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
3 Date: Wed, 18 Jul 2018 15:40:26 -0500
4 Subject: PCI: OF: Fix I/O space page leak
5
6 From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
7
8 commit a5fb9fb023a1435f2b42bccd7f547560f3a21dc3 upstream.
9
10 When testing the R-Car PCIe driver on the Condor board, if the PCIe PHY
11 driver was left disabled, the kernel crashed with this BUG:
12
13 kernel BUG at lib/ioremap.c:72!
14 Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
15 Modules linked in:
16 CPU: 0 PID: 39 Comm: kworker/0:1 Not tainted 4.17.0-dirty #1092
17 Hardware name: Renesas Condor board based on r8a77980 (DT)
18 Workqueue: events deferred_probe_work_func
19 pstate: 80000005 (Nzcv daif -PAN -UAO)
20 pc : ioremap_page_range+0x370/0x3c8
21 lr : ioremap_page_range+0x40/0x3c8
22 sp : ffff000008da39e0
23 x29: ffff000008da39e0 x28: 00e8000000000f07
24 x27: ffff7dfffee00000 x26: 0140000000000000
25 x25: ffff7dfffef00000 x24: 00000000000fe100
26 x23: ffff80007b906000 x22: ffff000008ab8000
27 x21: ffff000008bb1d58 x20: ffff7dfffef00000
28 x19: ffff800009c30fb8 x18: 0000000000000001
29 x17: 00000000000152d0 x16: 00000000014012d0
30 x15: 0000000000000000 x14: 0720072007200720
31 x13: 0720072007200720 x12: 0720072007200720
32 x11: 0720072007300730 x10: 00000000000000ae
33 x9 : 0000000000000000 x8 : ffff7dffff000000
34 x7 : 0000000000000000 x6 : 0000000000000100
35 x5 : 0000000000000000 x4 : 000000007b906000
36 x3 : ffff80007c61a880 x2 : ffff7dfffeefffff
37 x1 : 0000000040000000 x0 : 00e80000fe100f07
38 Process kworker/0:1 (pid: 39, stack limit = 0x (ptrval))
39 Call trace:
40 ioremap_page_range+0x370/0x3c8
41 pci_remap_iospace+0x7c/0xac
42 pci_parse_request_of_pci_ranges+0x13c/0x190
43 rcar_pcie_probe+0x4c/0xb04
44 platform_drv_probe+0x50/0xbc
45 driver_probe_device+0x21c/0x308
46 __device_attach_driver+0x98/0xc8
47 bus_for_each_drv+0x54/0x94
48 __device_attach+0xc4/0x12c
49 device_initial_probe+0x10/0x18
50 bus_probe_device+0x90/0x98
51 deferred_probe_work_func+0xb0/0x150
52 process_one_work+0x12c/0x29c
53 worker_thread+0x200/0x3fc
54 kthread+0x108/0x134
55 ret_from_fork+0x10/0x18
56 Code: f9004ba2 54000080 aa0003fb 17ffff48 (d4210000)
57
58 It turned out that pci_remap_iospace() wasn't undone when the driver's
59 probe failed, and since devm_phy_optional_get() returned -EPROBE_DEFER,
60 the probe was retried, finally causing the BUG due to trying to remap
61 already remapped pages.
62
63 Introduce the devm_pci_remap_iospace() managed API and replace the
64 pci_remap_iospace() call with it to fix the bug.
65
66 Fixes: dbf9826d5797 ("PCI: generic: Convert to DT resource parsing API")
67 Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
68 [lorenzo.pieralisi@arm.com: split commit/updated the commit log]
69 Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
70 Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
71 Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
72 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
73
74 ---
75 drivers/pci/host/pci-host-common.c | 2 -
76 drivers/pci/host/pcie-rcar.c | 2 -
77 drivers/pci/pci.c | 38 +++++++++++++++++++++++++++++++++++++
78 include/linux/pci.h | 2 +
79 4 files changed, 42 insertions(+), 2 deletions(-)
80
81 --- a/drivers/pci/host/pci-host-common.c
82 +++ b/drivers/pci/host/pci-host-common.c
83 @@ -45,7 +45,7 @@ static int gen_pci_parse_request_of_pci_
84
85 switch (resource_type(res)) {
86 case IORESOURCE_IO:
87 - err = pci_remap_iospace(res, iobase);
88 + err = devm_pci_remap_iospace(dev, res, iobase);
89 if (err) {
90 dev_warn(dev, "error %d: failed to map resource %pR\n",
91 err, res);
92 --- a/drivers/pci/host/pcie-rcar.c
93 +++ b/drivers/pci/host/pcie-rcar.c
94 @@ -1105,7 +1105,7 @@ static int rcar_pcie_parse_request_of_pc
95 struct resource *res = win->res;
96
97 if (resource_type(res) == IORESOURCE_IO) {
98 - err = pci_remap_iospace(res, iobase);
99 + err = devm_pci_remap_iospace(dev, res, iobase);
100 if (err) {
101 dev_warn(dev, "error %d: failed to map resource %pR\n",
102 err, res);
103 --- a/drivers/pci/pci.c
104 +++ b/drivers/pci/pci.c
105 @@ -3446,6 +3446,44 @@ void pci_unmap_iospace(struct resource *
106 }
107 EXPORT_SYMBOL(pci_unmap_iospace);
108
109 +static void devm_pci_unmap_iospace(struct device *dev, void *ptr)
110 +{
111 + struct resource **res = ptr;
112 +
113 + pci_unmap_iospace(*res);
114 +}
115 +
116 +/**
117 + * devm_pci_remap_iospace - Managed pci_remap_iospace()
118 + * @dev: Generic device to remap IO address for
119 + * @res: Resource describing the I/O space
120 + * @phys_addr: physical address of range to be mapped
121 + *
122 + * Managed pci_remap_iospace(). Map is automatically unmapped on driver
123 + * detach.
124 + */
125 +int devm_pci_remap_iospace(struct device *dev, const struct resource *res,
126 + phys_addr_t phys_addr)
127 +{
128 + const struct resource **ptr;
129 + int error;
130 +
131 + ptr = devres_alloc(devm_pci_unmap_iospace, sizeof(*ptr), GFP_KERNEL);
132 + if (!ptr)
133 + return -ENOMEM;
134 +
135 + error = pci_remap_iospace(res, phys_addr);
136 + if (error) {
137 + devres_free(ptr);
138 + } else {
139 + *ptr = res;
140 + devres_add(dev, ptr);
141 + }
142 +
143 + return error;
144 +}
145 +EXPORT_SYMBOL(devm_pci_remap_iospace);
146 +
147 /**
148 * devm_pci_remap_cfgspace - Managed pci_remap_cfgspace()
149 * @dev: Generic device to remap IO address for
150 --- a/include/linux/pci.h
151 +++ b/include/linux/pci.h
152 @@ -1235,6 +1235,8 @@ int pci_register_io_range(phys_addr_t ad
153 unsigned long pci_address_to_pio(phys_addr_t addr);
154 phys_addr_t pci_pio_to_address(unsigned long pio);
155 int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
156 +int devm_pci_remap_iospace(struct device *dev, const struct resource *res,
157 + phys_addr_t phys_addr);
158 void pci_unmap_iospace(struct resource *res);
159 void __iomem *devm_pci_remap_cfgspace(struct device *dev,
160 resource_size_t offset,