]>
Commit | Line | Data |
---|---|---|
a3852365 GKH |
1 | From 2f01a33bd26545c16fea7592697f7f15c416402b Mon Sep 17 00:00:00 2001 |
2 | From: Peter Chen <peter.chen@freescale.com> | |
3 | Date: Tue, 21 Jul 2015 09:51:29 +0800 | |
4 | Subject: usb: chipidea: ehci_init_driver is intended to call one time | |
5 | ||
6 | From: Peter Chen <peter.chen@freescale.com> | |
7 | ||
8 | commit 2f01a33bd26545c16fea7592697f7f15c416402b upstream. | |
9 | ||
10 | The ehci_init_driver is used to initialize hcd APIs for each | |
11 | ehci controller driver, it is designed to be called only one time | |
12 | and before driver register is called. The current design will | |
13 | cause ehci_init_driver is called multiple times at probe process, | |
14 | it will cause hc_driver's initialization affect current running hcd. | |
15 | ||
16 | We run out NULL pointer dereference problem when one hcd is started | |
17 | by module_init, and the other is started by otg thread at SMP platform. | |
18 | The reason for this problem is ehci_init_driver will do memory copy | |
19 | for current uniform hc_driver, and this memory copy will do memset (as 0) | |
20 | first, so when the first hcd is running usb_add_hcd, and the second | |
21 | hcd may clear the uniform hc_driver's space (at ehci_init_driver), | |
22 | then the first hcd will meet NULL pointer at the same time. | |
23 | ||
24 | See below two logs: | |
25 | ||
26 | LOG_1: | |
27 | ci_hdrc ci_hdrc.0: EHCI Host Controller | |
28 | ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1 | |
29 | ci_hdrc ci_hdrc.1: doesn't support gadget | |
30 | Unable to handle kernel NULL pointer dereference at virtual address 00000014 | |
31 | pgd = 80004000 | |
32 | [00000014] *pgd=00000000 | |
33 | Internal error: Oops: 805 [#1] PREEMPT SMP ARM | |
34 | Modules linked in: | |
35 | CPU: 0 PID: 108 Comm: kworker/u8:2 Not tainted 3.14.38-222193-g24b2734-dirty #25 | |
36 | Workqueue: ci_otg ci_otg_work | |
37 | task: d839ec00 ti: d8400000 task.ti: d8400000 | |
38 | PC is at ehci_run+0x4c/0x284 | |
39 | LR is at _raw_spin_unlock_irqrestore+0x28/0x54 | |
40 | pc : [<8041f9a0>] lr : [<8070ea84>] psr: 60000113 | |
41 | sp : d8401e30 ip : 00000000 fp : d8004400 | |
42 | r10: 00000001 r9 : 00000001 r8 : 00000000 | |
43 | r7 : 00000000 r6 : d8419940 r5 : 80dd24c0 r4 : d8419800 | |
44 | r3 : 8001d060 r2 : 00000000 r1 : 00000001 r0 : 00000000 | |
45 | Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel | |
46 | Control: 10c53c7d Table: 1000404a DAC: 00000015 | |
47 | Process kworker/u8:2 (pid: 108, stack limit = 0xd8400238) | |
48 | Stack: (0xd8401e30 to 0xd8402000) | |
49 | 1e20: d87523c0 d8401e48 66667562 d8419800 | |
50 | 1e40: 00000000 00000000 d8419800 00000000 00000000 00000000 d84198b0 8040fcdc | |
51 | 1e60: 00000000 80dd320c d8477610 d8419c00 d803d010 d8419800 00000000 00000000 | |
52 | 1e80: d8004400 00000000 d8400008 80431494 80431374 d803d100 d803d010 d803d1ac | |
53 | 1ea0: 00000000 80432428 804323d4 d803d100 00000001 80435eb8 80e0d0bc d803d100 | |
54 | 1ec0: 00000006 80436458 00000000 d803d100 80e92ec8 80436f44 d803d010 d803d100 | |
55 | 1ee0: d83fde00 8043292c d8752710 d803d1f4 d803d010 8042ddfc 8042ddb8 d83f3b00 | |
56 | 1f00: d803d1f4 80042b60 00000000 00000003 00000001 00000001 80054598 d83f3b00 | |
57 | 1f20: d8004400 d83f3b18 d8004414 d8400000 80e3957b 00000089 d8004400 80043814 | |
58 | 1f40: d839ec00 00000000 d83fcd80 d83f3b00 800436e4 00000000 00000000 00000000 | |
59 | 1f60: 00000000 80048f34 00000000 00000000 00000000 d83f3b00 00000000 00000000 | |
60 | 1f80: d8401f80 d8401f80 00000000 00000000 d8401f90 d8401f90 d8401fac d83fcd80 | |
61 | 1fa0: 80048e68 00000000 00000000 8000e538 00000000 00000000 00000000 00000000 | |
62 | 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | |
63 | 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 | |
64 | [<8041f9a0>] (ehci_run) from [<8040fcdc>] (usb_add_hcd+0x248/0x6e8) | |
65 | [<8040fcdc>] (usb_add_hcd) from [<80431494>] (host_start+0x120/0x2e4) | |
66 | [<80431494>] (host_start) from [<80432428>] (ci_otg_start_host+0x54/0xbc) | |
67 | [<80432428>] (ci_otg_start_host) from [<80435eb8>] (otg_set_protocol+0xa4/0xd0) | |
68 | [<80435eb8>] (otg_set_protocol) from [<80436458>] (otg_set_state+0x574/0xc58) | |
69 | [<80436458>] (otg_set_state) from [<80436f44>] (otg_statemachine+0x408/0x46c) | |
70 | [<80436f44>] (otg_statemachine) from [<8043292c>] (ci_otg_fsm_work+0x3c/0x190) | |
71 | [<8043292c>] (ci_otg_fsm_work) from [<8042ddfc>] (ci_otg_work+0x44/0x1c4) | |
72 | [<8042ddfc>] (ci_otg_work) from [<80042b60>] (process_one_work+0xf4/0x35c) | |
73 | [<80042b60>] (process_one_work) from [<80043814>] (worker_thread+0x130/0x3bc) | |
74 | [<80043814>] (worker_thread) from [<80048f34>] (kthread+0xcc/0xe4) | |
75 | [<80048f34>] (kthread) from [<8000e538>] (ret_from_fork+0x14/0x3c) | |
76 | Code: e5953018 e3530000 0a000000 e12fff33 (e5878014) | |
77 | ||
78 | LOG_2: | |
79 | ci_hdrc ci_hdrc.0: EHCI Host Controller | |
80 | ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1 | |
81 | ci_hdrc ci_hdrc.1: doesn't support gadget | |
82 | Unable to handle kernel NULL pointer dereference at virtual address 00000000 | |
83 | pgd = 80004000 | |
84 | [00000000] *pgd=00000000 | |
85 | In Online 00:00ternal e Offline rror: Oops: 80000005 [#1] PREEMPT SMP ARM | |
86 | Modules linked in: | |
87 | CPU: 0 PID: 108 Comm: kworker/u8:2 Not tainted 3.14.38-02007-g24b2734-dirty #127 | |
88 | Workque Online 00:00ue: ci_o Offline tg ci_otg_work | |
89 | Online 00:00task: d8 Offline 39ec00 ti: d83ea000 task.ti: d83ea000 | |
90 | PC is at 0x0 | |
91 | LR is at usb_add_hcd+0x248/0x6e8 | |
92 | pc : [<00000000>] lr : [<8040f644>] psr: 60000113 | |
93 | sp : d83ebe60 ip : 00000000 fp : d8004400 | |
94 | r10: 00000001 r9 : 00000001 r8 : d85fd4b0 | |
95 | r7 : 00000000 r6 : 00000000 r5 : 00000000 r4 : d85fd400 | |
96 | r3 : 00000000 r2 : d85fd4f4 r1 : 80410178 r0 : d85fd400 | |
97 | Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel | |
98 | Control: 10c53c7d Table: 1000404a DAC: 00000015 | |
99 | Process kworker/u8:2 (pid: 108, stack limit = 0xd83ea238) | |
100 | Stack: (0xd83ebe60 to 0xd83ec000) | |
101 | be60: 00000000 80dd920c d8654e10 d85fd800 d803e010 d85fd400 00000000 00000000 | |
102 | be80: d8004400 00000000 d83ea008 80430e34 80430d14 d803e100 d803e010 d803e1ac | |
103 | bea0: 00000000 80431dc8 80431d74 d803e100 00000001 80435858 80e130bc d803e100 | |
104 | bec0: 00000006 80435df8 00000000 d803e100 80e98ec8 804368e4 d803e010 d803e100 | |
105 | bee0: d86e8100 804322cc d86cf050 d803e1f4 d803e010 8042d79c 8042d758 d83cf900 | |
106 | bf00: d803e1f4 80042b78 00000000 00000003 00000001 00000001 800545e8 d83cf900 | |
107 | bf20: d8004400 d83cf918 d8004414 d83ea000 80e3f57b 00000089 d8004400 8004382c | |
108 | bf40: d839ec00 00000000 d8393780 d83cf900 800436fc 00000000 00000000 00000000 | |
109 | bf60: 00000000 80048f50 80e019f4 00000000 0000264c d83cf900 00000000 00000000 | |
110 | bf80: d83ebf80 d83ebf80 00000000 00000000 d83ebf90 d83ebf90 d83ebfac d8393780 | |
111 | bfa0: 80048e84 00000000 00000000 8000e538 00000000 00000000 00000000 00000000 | |
112 | bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | |
113 | bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ee66e85d 133ebd03 | |
114 | [<804 Online 00:000f644>] Offline (usb_add_hcd) from [<80430e34>] (host_start+0x120/0x2e4) | |
115 | [<80430e34>] (host_start) from [<80431dc8>] (ci_otg_start_host+0x54/0xbc) | |
116 | [<80431dc8>] (ci_otg_start_host) from [<80435858>] (otg_set_protocol+0xa4/0xd0) | |
117 | [<80435858>] (otg_set_protocol) from [<80435df8>] (otg_set_state+0x574/0xc58) | |
118 | [<80435df8>] (otg_set_state) from [<804368e4>] (otg_statemachine+0x408/0x46c) | |
119 | [<804368e4>] (otg_statemachine) from [<804322cc>] (ci_otg_fsm_work+0x3c/0x190) | |
120 | [<804322cc>] (ci_otg_fsm_work) from [<8042d79c>] (ci_otg_work+0x44/0x1c4) | |
121 | [<8042d79c>] (ci_otg_work) from [<80042b78>] (process_one_work+0xf4/0x35c) | |
122 | [<80042b78>] (process_one_work) from [<8004382c>] (worker_thread+0x130/0x3bc) | |
123 | [<8004382c>] (worker_thread) from [<80048f50>] (kthread+0xcc/0xe4) | |
124 | [<80048f50>] (kthread) from [<8000e538>] (ret_from_fork+0x14/0x3c) | |
125 | Code: bad PC value | |
126 | ||
127 | Cc: Jun Li <jun.li@freescale.com> | |
128 | Cc: Alan Stern <stern@rowland.harvard.edu> | |
129 | Acked-by: Alan Stern <stern@rowland.harvard.edu> | |
130 | Signed-off-by: Peter Chen <peter.chen@freescale.com> | |
131 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
132 | ||
133 | --- | |
134 | drivers/usb/chipidea/core.c | 13 ++++++++++++- | |
135 | drivers/usb/chipidea/host.c | 7 +++++-- | |
136 | drivers/usb/chipidea/host.h | 6 ++++++ | |
137 | 3 files changed, 23 insertions(+), 3 deletions(-) | |
138 | ||
139 | --- a/drivers/usb/chipidea/core.c | |
140 | +++ b/drivers/usb/chipidea/core.c | |
141 | @@ -1024,7 +1024,18 @@ static struct platform_driver ci_hdrc_dr | |
142 | }, | |
143 | }; | |
144 | ||
145 | -module_platform_driver(ci_hdrc_driver); | |
146 | +static int __init ci_hdrc_platform_register(void) | |
147 | +{ | |
148 | + ci_hdrc_host_driver_init(); | |
149 | + return platform_driver_register(&ci_hdrc_driver); | |
150 | +} | |
151 | +module_init(ci_hdrc_platform_register); | |
152 | + | |
153 | +static void __exit ci_hdrc_platform_unregister(void) | |
154 | +{ | |
155 | + platform_driver_unregister(&ci_hdrc_driver); | |
156 | +} | |
157 | +module_exit(ci_hdrc_platform_unregister); | |
158 | ||
159 | MODULE_ALIAS("platform:ci_hdrc"); | |
160 | MODULE_LICENSE("GPL v2"); | |
161 | --- a/drivers/usb/chipidea/host.c | |
162 | +++ b/drivers/usb/chipidea/host.c | |
163 | @@ -237,9 +237,12 @@ int ci_hdrc_host_init(struct ci_hdrc *ci | |
164 | rdrv->name = "host"; | |
165 | ci->roles[CI_ROLE_HOST] = rdrv; | |
166 | ||
167 | + return 0; | |
168 | +} | |
169 | + | |
170 | +void ci_hdrc_host_driver_init(void) | |
171 | +{ | |
172 | ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides); | |
173 | orig_bus_suspend = ci_ehci_hc_driver.bus_suspend; | |
174 | ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend; | |
175 | - | |
176 | - return 0; | |
177 | } | |
178 | --- a/drivers/usb/chipidea/host.h | |
179 | +++ b/drivers/usb/chipidea/host.h | |
180 | @@ -5,6 +5,7 @@ | |
181 | ||
182 | int ci_hdrc_host_init(struct ci_hdrc *ci); | |
183 | void ci_hdrc_host_destroy(struct ci_hdrc *ci); | |
184 | +void ci_hdrc_host_driver_init(void); | |
185 | ||
186 | #else | |
187 | ||
188 | @@ -17,6 +18,11 @@ static inline void ci_hdrc_host_destroy( | |
189 | { | |
190 | ||
191 | } | |
192 | + | |
193 | +static void ci_hdrc_host_driver_init(void) | |
194 | +{ | |
195 | + | |
196 | +} | |
197 | ||
198 | #endif | |
199 |