]>
Commit | Line | Data |
---|---|---|
f121e093 GKH |
1 | From 52bba9809a954d72bc77773bd560b9724b495eb7 Mon Sep 17 00:00:00 2001 |
2 | From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | |
3 | Date: Mon, 19 Jan 2015 09:57:13 +0000 | |
4 | Subject: clk: Fix debugfs clk removal before inited | |
5 | ||
6 | From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | |
7 | ||
8 | commit 52bba9809a954d72bc77773bd560b9724b495eb7 upstream. | |
9 | ||
10 | Some of the clks can be registered & unregistered before the clk related debugfs | |
11 | entries are initialized at late_initcall. In the unregister path checking for only | |
12 | dentry before clk_debug_init() would lead dangling pointers in the debug clk list, | |
13 | because the list is already populated in register path and the clk pointer freed in | |
14 | unregister path. | |
15 | The side effect of not removing it from the list is either a null pointer | |
16 | dereference or if lucky to boot the system, the number of clk entries in | |
17 | debugfs disappear. | |
18 | ||
19 | We could add more checks like if (inited && !clk->dentry) but just removing | |
20 | the check for dentry made more sense as debugfs_remove_recursive() seems to be | |
21 | safe with null pointers. This will ensure that the unregistering clk would be | |
22 | removed from the debug list in all the code paths. | |
23 | ||
24 | Without this patch kernel would crash with log: | |
25 | Unable to handle kernel NULL pointer dereference at virtual address 00000000 | |
26 | pgd = c0204000 | |
27 | [00000000] *pgd=00000000 | |
28 | Internal error: Oops: 5 [#1] SMP ARM | |
29 | Modules linked in: | |
30 | CPU: 1 PID: 1 Comm: swapper/0 Tainted: G B 3.19.0-rc3-00007-g412f9ba-dirty #840 | |
31 | Hardware name: Qualcomm (Flattened Device Tree) | |
32 | task: ed948000 ti: ed944000 task.ti: ed944000 | |
33 | PC is at strlen+0xc/0x40 | |
34 | LR is at __create_file+0x64/0x1dc | |
35 | pc : [<c04ee604>] lr : [<c049f1c4>] psr: 60000013 | |
36 | sp : ed945e40 ip : ed945e50 fp : ed945e4c | |
37 | r10: 00000000 r9 : c1006094 r8 : 00000000 | |
38 | r7 : 000041ed r6 : 00000000 r5 : ed4af998 r4 : c11b5e28 | |
39 | r3 : 00000000 r2 : ed945e38 r1 : a0000013 r0 : 00000000 | |
40 | Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel | |
41 | Control: 10c5787d Table: 8020406a DAC: 00000015 | |
42 | Process swapper/0 (pid: 1, stack limit = 0xed944248) | |
43 | Stack: (0xed945e40 to 0xed946000) | |
44 | 5e40: ed945e7c ed945e50 c049f1c4 c04ee604 c0fc2fa4 00000000 ecb748c0 c11c2b80 | |
45 | 5e60: c0beec04 0000011c c0fc2fa4 00000000 ed945e94 ed945e80 c049f3e0 c049f16c | |
46 | 5e80: 00000000 00000000 ed945eac ed945e98 c08cbc50 c049f3c0 ecb748c0 c11c2b80 | |
47 | 5ea0: ed945ed4 ed945eb0 c0fc3080 c08cbc30 c0beec04 c107e1d8 ecdf0600 c107e1d8 | |
48 | 5ec0: c107e1d8 ecdf0600 ed945f54 ed945ed8 c0208ed4 c0fc2fb0 c026a784 c04ee628 | |
49 | 5ee0: ed945f0c ed945ef0 c0f5d600 c04ee604 c0f5d5ec ef7fcc7d c0b40ecc 0000011c | |
50 | 5f00: ed945f54 ed945f10 c026a994 c0f5d5f8 c04ecc00 00000007 ef7fcc95 00000007 | |
51 | 5f20: c0e90744 c0dd0884 ed945f54 c106cde0 00000007 c117f8c0 0000011c c0f5d5ec | |
52 | 5f40: c1006094 c100609c ed945f94 ed945f58 c0f5de34 c0208e50 00000007 00000007 | |
53 | 5f60: c0f5d5ec be9b5ae0 00000000 c117f8c0 c0af1680 00000000 00000000 00000000 | |
54 | 5f80: 00000000 00000000 ed945fac ed945f98 c0af169c c0f5dd2c ed944000 00000000 | |
55 | 5fa0: 00000000 ed945fb0 c020f298 c0af168c 00000000 00000000 00000000 00000000 | |
56 | 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | |
57 | 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 ebcc6d33 bfffca73 | |
58 | [<c04ee604>] (strlen) from [<c049f1c4>] (__create_file+0x64/0x1dc) | |
59 | [<c049f1c4>] (__create_file) from [<c049f3e0>] (debugfs_create_dir+0x2c/0x34) | |
60 | [<c049f3e0>] (debugfs_create_dir) from [<c08cbc50>] (clk_debug_create_one+0x2c/0x16c) | |
61 | [<c08cbc50>] (clk_debug_create_one) from [<c0fc3080>] (clk_debug_init+0xdc/0x144) | |
62 | [<c0fc3080>] (clk_debug_init) from [<c0208ed4>] (do_one_initcall+0x90/0x1e0) | |
63 | [<c0208ed4>] (do_one_initcall) from [<c0f5de34>] (kernel_init_freeable+0x114/0x1e0) | |
64 | [<c0f5de34>] (kernel_init_freeable) from [<c0af169c>] (kernel_init+0x1c/0xfc) | |
65 | [<c0af169c>] (kernel_init) from [<c020f298>] (ret_from_fork+0x14/0x3c) | |
66 | Code: c0b40ecc e1a0c00d e92dd800 e24cb004 (e5d02000) | |
67 | ---[ end trace b940e45b5e25c1e7 ]--- | |
68 | ||
69 | Fixes: 6314b6796e3c "clk: Don't hold prepare_lock across debugfs creation" | |
70 | Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | |
71 | Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> | |
72 | Signed-off-by: Michael Turquette <mturquette@linaro.org> | |
73 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
74 | ||
75 | --- | |
76 | drivers/clk/clk.c | 4 ---- | |
77 | 1 file changed, 4 deletions(-) | |
78 | ||
79 | --- a/drivers/clk/clk.c | |
80 | +++ b/drivers/clk/clk.c | |
81 | @@ -343,13 +343,9 @@ unlock: | |
82 | static void clk_debug_unregister(struct clk *clk) | |
83 | { | |
84 | mutex_lock(&clk_debug_lock); | |
85 | - if (!clk->dentry) | |
86 | - goto out; | |
87 | - | |
88 | hlist_del_init(&clk->debug_node); | |
89 | debugfs_remove_recursive(clk->dentry); | |
90 | clk->dentry = NULL; | |
91 | -out: | |
92 | mutex_unlock(&clk_debug_lock); | |
93 | } | |
94 |