]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.19.34/soc-tegra-fuse-fix-illegal-free-of-io-base-address.patch
Linux 4.19.34
[thirdparty/kernel/stable-queue.git] / releases / 4.19.34 / soc-tegra-fuse-fix-illegal-free-of-io-base-address.patch
1 From 39ccc67166b242361750ba97152e0480eec4394f Mon Sep 17 00:00:00 2001
2 From: Timo Alho <talho@nvidia.com>
3 Date: Sun, 30 Dec 2018 17:58:08 +0200
4 Subject: soc/tegra: fuse: Fix illegal free of IO base address
5
6 [ Upstream commit 51294bf6b9e897d595466dcda5a3f2751906a200 ]
7
8 On cases where device tree entries for fuse and clock provider are in
9 different order, fuse driver needs to defer probing. This leads to
10 freeing incorrect IO base address as the fuse->base variable gets
11 overwritten once during first probe invocation. This leads to the
12 following spew during boot:
13
14 [ 3.082285] Trying to vfree() nonexistent vm area (00000000cfe8fd94)
15 [ 3.082308] WARNING: CPU: 5 PID: 126 at /hdd/l4t/kernel/stable/mm/vmalloc.c:1511 __vunmap+0xcc/0xd8
16 [ 3.082318] Modules linked in:
17 [ 3.082330] CPU: 5 PID: 126 Comm: kworker/5:1 Tainted: G S 4.19.7-tegra-gce119d3 #1
18 [ 3.082340] Hardware name: quill (DT)
19 [ 3.082353] Workqueue: events deferred_probe_work_func
20 [ 3.082364] pstate: 40000005 (nZcv daif -PAN -UAO)
21 [ 3.082372] pc : __vunmap+0xcc/0xd8
22 [ 3.082379] lr : __vunmap+0xcc/0xd8
23 [ 3.082385] sp : ffff00000a1d3b60
24 [ 3.082391] x29: ffff00000a1d3b60 x28: 0000000000000000
25 [ 3.082402] x27: 0000000000000000 x26: ffff000008e8b610
26 [ 3.082413] x25: 0000000000000000 x24: 0000000000000009
27 [ 3.082423] x23: ffff000009221a90 x22: ffff000009f6d000
28 [ 3.082432] x21: 0000000000000000 x20: 0000000000000000
29 [ 3.082442] x19: ffff000009f6d000 x18: ffffffffffffffff
30 [ 3.082452] x17: 0000000000000000 x16: 0000000000000000
31 [ 3.082462] x15: ffff0000091396c8 x14: 0720072007200720
32 [ 3.082471] x13: 0720072007200720 x12: 0720072907340739
33 [ 3.082481] x11: 0764076607380765 x10: 0766076307300730
34 [ 3.082491] x9 : 0730073007300730 x8 : 0730073007280720
35 [ 3.082501] x7 : 0761076507720761 x6 : 0000000000000102
36 [ 3.082510] x5 : 0000000000000000 x4 : 0000000000000000
37 [ 3.082519] x3 : ffffffffffffffff x2 : ffff000009150ff8
38 [ 3.082528] x1 : 3d95b1429fff5200 x0 : 0000000000000000
39 [ 3.082538] Call trace:
40 [ 3.082545] __vunmap+0xcc/0xd8
41 [ 3.082552] vunmap+0x24/0x30
42 [ 3.082561] __iounmap+0x2c/0x38
43 [ 3.082569] tegra_fuse_probe+0xc8/0x118
44 [ 3.082577] platform_drv_probe+0x50/0xa0
45 [ 3.082585] really_probe+0x1b0/0x288
46 [ 3.082593] driver_probe_device+0x58/0x100
47 [ 3.082601] __device_attach_driver+0x98/0xf0
48 [ 3.082609] bus_for_each_drv+0x64/0xc8
49 [ 3.082616] __device_attach+0xd8/0x130
50 [ 3.082624] device_initial_probe+0x10/0x18
51 [ 3.082631] bus_probe_device+0x90/0x98
52 [ 3.082638] deferred_probe_work_func+0x74/0xb0
53 [ 3.082649] process_one_work+0x1e0/0x318
54 [ 3.082656] worker_thread+0x228/0x450
55 [ 3.082664] kthread+0x128/0x130
56 [ 3.082672] ret_from_fork+0x10/0x18
57 [ 3.082678] ---[ end trace 0810fe6ba772c1c7 ]---
58
59 Fix this by retaining the value of fuse->base until driver has
60 successfully probed.
61
62 Signed-off-by: Timo Alho <talho@nvidia.com>
63 Acked-by: Jon Hunter <jonathanh@nvidia.com>
64 Signed-off-by: Thierry Reding <treding@nvidia.com>
65 Signed-off-by: Sasha Levin <sashal@kernel.org>
66 ---
67 drivers/soc/tegra/fuse/fuse-tegra.c | 12 +++++++++---
68 1 file changed, 9 insertions(+), 3 deletions(-)
69
70 diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
71 index a33ee8ef8b6b..51625703399e 100644
72 --- a/drivers/soc/tegra/fuse/fuse-tegra.c
73 +++ b/drivers/soc/tegra/fuse/fuse-tegra.c
74 @@ -137,13 +137,17 @@ static int tegra_fuse_probe(struct platform_device *pdev)
75 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
76 fuse->phys = res->start;
77 fuse->base = devm_ioremap_resource(&pdev->dev, res);
78 - if (IS_ERR(fuse->base))
79 - return PTR_ERR(fuse->base);
80 + if (IS_ERR(fuse->base)) {
81 + err = PTR_ERR(fuse->base);
82 + fuse->base = base;
83 + return err;
84 + }
85
86 fuse->clk = devm_clk_get(&pdev->dev, "fuse");
87 if (IS_ERR(fuse->clk)) {
88 dev_err(&pdev->dev, "failed to get FUSE clock: %ld",
89 PTR_ERR(fuse->clk));
90 + fuse->base = base;
91 return PTR_ERR(fuse->clk);
92 }
93
94 @@ -152,8 +156,10 @@ static int tegra_fuse_probe(struct platform_device *pdev)
95
96 if (fuse->soc->probe) {
97 err = fuse->soc->probe(fuse);
98 - if (err < 0)
99 + if (err < 0) {
100 + fuse->base = base;
101 return err;
102 + }
103 }
104
105 if (tegra_fuse_create_sysfs(&pdev->dev, fuse->soc->info->size,
106 --
107 2.19.1
108