]>
Commit | Line | Data |
---|---|---|
81add72f GKH |
1 | From 72b5322f11ff0abf6a52b3007486656578d2c982 Mon Sep 17 00:00:00 2001 |
2 | From: Lai Jiangshan <laijs@cn.fujitsu.com> | |
3 | Date: Mon, 3 Jun 2013 17:17:15 +0800 | |
4 | Subject: clk: remove notifier from list before freeing it | |
5 | ||
6 | From: Lai Jiangshan <laijs@cn.fujitsu.com> | |
7 | ||
8 | commit 72b5322f11ff0abf6a52b3007486656578d2c982 upstream. | |
9 | ||
10 | The @cn is stay in @clk_notifier_list after it is freed, it cause | |
11 | memory corruption. | |
12 | ||
13 | Example, if @clk is registered(first), unregistered(first), | |
14 | registered(second), unregistered(second). | |
15 | ||
16 | The freed @cn will be used when @clk is registered(second), | |
17 | and the bug will be happened when @clk is unregistered(second): | |
18 | ||
19 | [ 517.040000] clk_notif_dbg clk_notif_dbg.1: clk_notifier_unregister() | |
20 | [ 517.040000] Unable to handle kernel paging request at virtual address 00df3008 | |
21 | [ 517.050000] pgd = ed858000 | |
22 | [ 517.050000] [00df3008] *pgd=00000000 | |
23 | [ 517.060000] Internal error: Oops: 5 [#1] PREEMPT SMP ARM | |
24 | [ 517.060000] Modules linked in: clk_notif_dbg(O-) [last unloaded: clk_notif_dbg] | |
25 | [ 517.060000] CPU: 1 PID: 499 Comm: modprobe Tainted: G O 3.10.0-rc3-00119-ga93cb29-dirty #85 | |
26 | [ 517.060000] task: ee1e0180 ti: ee3e6000 task.ti: ee3e6000 | |
27 | [ 517.060000] PC is at srcu_readers_seq_idx+0x48/0x84 | |
28 | [ 517.060000] LR is at srcu_readers_seq_idx+0x60/0x84 | |
29 | [ 517.060000] pc : [<c0052720>] lr : [<c0052738>] psr: 80070013 | |
30 | [ 517.060000] sp : ee3e7d48 ip : 00000000 fp : ee3e7d6c | |
31 | [ 517.060000] r10: 00000000 r9 : ee3e6000 r8 : 00000000 | |
32 | [ 517.060000] r7 : ed84fe4c r6 : c068ec90 r5 : c068e430 r4 : 00000000 | |
33 | [ 517.060000] r3 : 00df3000 r2 : 00000000 r1 : 00000002 r0 : 00000000 | |
34 | [ 517.060000] Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user | |
35 | [ 517.060000] Control: 18c5387d Table: 2d85804a DAC: 00000015 | |
36 | [ 517.060000] Process modprobe (pid: 499, stack limit = 0xee3e6238) | |
37 | [ 517.060000] Stack: (0xee3e7d48 to 0xee3e8000) | |
38 | .... | |
39 | [ 517.060000] [<c0052720>] (srcu_readers_seq_idx+0x48/0x84) from [<c0052790>] (try_check_zero+0x34/0xfc) | |
40 | [ 517.060000] [<c0052790>] (try_check_zero+0x34/0xfc) from [<c00528b0>] (srcu_advance_batches+0x58/0x114) | |
41 | [ 517.060000] [<c00528b0>] (srcu_advance_batches+0x58/0x114) from [<c0052c30>] (__synchronize_srcu+0x114/0x1ac) | |
42 | [ 517.060000] [<c0052c30>] (__synchronize_srcu+0x114/0x1ac) from [<c0052d14>] (synchronize_srcu+0x2c/0x34) | |
43 | [ 517.060000] [<c0052d14>] (synchronize_srcu+0x2c/0x34) from [<c0053a08>] (srcu_notifier_chain_unregister+0x68/0x74) | |
44 | [ 517.060000] [<c0053a08>] (srcu_notifier_chain_unregister+0x68/0x74) from [<c0375a78>] (clk_notifier_unregister+0x7c/0xc0) | |
45 | [ 517.060000] [<c0375a78>] (clk_notifier_unregister+0x7c/0xc0) from [<bf008034>] (clk_notif_dbg_remove+0x34/0x9c [clk_notif_dbg]) | |
46 | [ 517.060000] [<bf008034>] (clk_notif_dbg_remove+0x34/0x9c [clk_notif_dbg]) from [<c02bb974>] (platform_drv_remove+0x24/0x28) | |
47 | [ 517.060000] [<c02bb974>] (platform_drv_remove+0x24/0x28) from [<c02b9bf8>] (__device_release_driver+0x8c/0xd4) | |
48 | [ 517.060000] [<c02b9bf8>] (__device_release_driver+0x8c/0xd4) from [<c02ba680>] (driver_detach+0x9c/0xc4) | |
49 | [ 517.060000] [<c02ba680>] (driver_detach+0x9c/0xc4) from [<c02b99c4>] (bus_remove_driver+0xcc/0xfc) | |
50 | [ 517.060000] [<c02b99c4>] (bus_remove_driver+0xcc/0xfc) from [<c02bace4>] (driver_unregister+0x54/0x78) | |
51 | [ 517.060000] [<c02bace4>] (driver_unregister+0x54/0x78) from [<c02bbb44>] (platform_driver_unregister+0x1c/0x20) | |
52 | [ 517.060000] [<c02bbb44>] (platform_driver_unregister+0x1c/0x20) from [<bf0081f8>] (clk_notif_dbg_driver_exit+0x14/0x1c [clk_notif_dbg]) | |
53 | [ 517.060000] [<bf0081f8>] (clk_notif_dbg_driver_exit+0x14/0x1c [clk_notif_dbg]) from [<c00835e4>] (SyS_delete_module+0x200/0x28c) | |
54 | [ 517.060000] [<c00835e4>] (SyS_delete_module+0x200/0x28c) from [<c000edc0>] (ret_fast_syscall+0x0/0x48) | |
55 | [ 517.060000] Code: e5973004 e7911102 e0833001 e2881002 (e7933101) | |
56 | ||
57 | Reported-by: Sören Brinkmann <soren.brinkmann@xilinx.com> | |
58 | Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> | |
59 | Tested-by: Sören Brinkmann <soren.brinkmann@xilinx.com> | |
60 | Signed-off-by: Mike Turquette <mturquette@linaro.org> | |
61 | [mturquette@linaro.org: shortened $SUBJECT] | |
62 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
63 | ||
64 | --- | |
65 | drivers/clk/clk.c | 1 + | |
66 | 1 file changed, 1 insertion(+) | |
67 | ||
68 | --- a/drivers/clk/clk.c | |
69 | +++ b/drivers/clk/clk.c | |
70 | @@ -1453,6 +1453,7 @@ int clk_notifier_unregister(struct clk * | |
71 | /* XXX the notifier code should handle this better */ | |
72 | if (!cn->notifier_head.head) { | |
73 | srcu_cleanup_notifier_head(&cn->notifier_head); | |
74 | + list_del(&cn->node); | |
75 | kfree(cn); | |
76 | } | |
77 |