]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - 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
CommitLineData
ba172962
SL
1From 39ccc67166b242361750ba97152e0480eec4394f Mon Sep 17 00:00:00 2001
2From: Timo Alho <talho@nvidia.com>
3Date: Sun, 30 Dec 2018 17:58:08 +0200
4Subject: soc/tegra: fuse: Fix illegal free of IO base address
5
6[ Upstream commit 51294bf6b9e897d595466dcda5a3f2751906a200 ]
7
8On cases where device tree entries for fuse and clock provider are in
9different order, fuse driver needs to defer probing. This leads to
10freeing incorrect IO base address as the fuse->base variable gets
11overwritten once during first probe invocation. This leads to the
12following 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
59Fix this by retaining the value of fuse->base until driver has
60successfully probed.
61
62Signed-off-by: Timo Alho <talho@nvidia.com>
63Acked-by: Jon Hunter <jonathanh@nvidia.com>
64Signed-off-by: Thierry Reding <treding@nvidia.com>
65Signed-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
70diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
71index 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--
1072.19.1
108