diff options
author | Peter Chen <peter.chen@freescale.com> | 2015-07-02 09:41:03 +0800 |
---|---|---|
committer | Octavian Purdila <octavian.purdila@nxp.com> | 2017-02-23 14:21:42 +0200 |
commit | b9a07a4b56043e9d11e9a357491e70d533203746 (patch) | |
tree | ab5396702b267471fbc49904c5ba950a4936d70e /drivers/usb | |
parent | b87d0fc0b38fc3e4e58fc2263112bd32e8561804 (diff) |
MLK-11183-1 usb: chipidea: host: fix NULL pointer problem for fast load/unload module
The interrupt may occur (due to remove process may block interrupt)
after we remove hcd, in that case, we should not call hcd's interrupt
handler, otherwise, below NULL pointer dereference will occur, the reason
for this is we call free_irq later than hcd's. So after hcd has been
removed, we should not call hcd interrupt handler.
ci_hdrc ci_hdrc.0: remove, state 1
usb usb1: USB disconnect, device number 1
ci_hdrc ci_hdrc.0: USB bus 1 deregistered
[<800691e8>] (handle_irq_event) from [<8006c02c>] (handle_fasteoi_irq+0x84/0x14c)
[<8006c02c>] (handle_fasteoi_irq) from [<800687f4>] (generic_handle_irq+0x2c/0x3c)
[<800687f4>] (generic_handle_irq) from [<8000ed4c>] (handle_IRQ+0x40/0x90)
[<8000ed4c>] (handle_IRQ) from [<8000856c>] (gic_handle_irq+0x2c/0x5c)
[<8000856c>] (gic_handle_irq) from [<80012240>] (__irq_svc+0x40/0x70)
Exception stack(0x80db1f18 to 0x80db1f60)
1f00: 80db1f60 3b9aca00
1f20: 06f86934 0000000d 80dbe1c8 80dbe1c8 ee71e0d0 00000000 06f5bb01 0000000d
1f40: 80db0000 00000000 00000017 80db1f60 00000009 8049c19c 000d0013 ffffffff
[<80012240>] (__irq_svc) from [<8049c19c>] (cpuidle_enter_state+0x54/0xe4)
[<8049c19c>] (cpuidle_enter_state) from [<8049c2e0>] (cpuidle_idle_call+0xb4/0x14c)
[<8049c2e0>] (cpuidle_idle_call) from [<8000f07c>] (arch_cpu_idle+0x8/0x44)
[<8000f07c>] (arch_cpu_idle) from [<8006876c>] (cpu_startup_entry+0x100/0x14c)
[<8006876c>] (cpu_startup_entry) from [<80d52b10>] (start_kernel+0x350/0x35c)
--[ end trace 1160f590a7b228b3 ]--
Unable to handle kernel NULL pointer dereference at virtual address 000000b0
pgd = 80004000
[000000b0] *pgd=00000000
Internal error: Oops: 17 1 PREEMPT SMP ARM
Modules linked in: ci_hdrc_imx usbmisc_imx ci_hdrc udc_core ehci_hcd phy_mxs_usb mxc_v4l2_capture ipu_bg_overlay_sdc ipu_still ipu_prp_enc adv7180_tvin ipu_csi_enc v4l2_int_device ipu_fg_overlay_sdc mxc_mlb mxc_dcic evbug [last unloaded: phy_mxs_usb]
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 3.14.38-usb-host-otg-02047-ga4dec77 #13
task: 80dbbae8 ti: 80db0000 task.ti: 80db0000
PC is at usb_hcd_irq+0x4/0x38
LR is at handle_irq_event_percpu+0x50/0x180
pc : [<8040eed8>] lr : [<8006907c>] psr: a00d0193
sp : 80db1e98 ip : fffffffa fp : 00000000
r10: 80e1f13f r9 : d8009900 r8 : 0000004b
r7 : 00000000 r6 : 00000000 r5 : d800995c r4 : d8f2dec0
r3 : d2234010 r2 : d2234010 r1 : 00000000 r0 : 0000004b
Flags: NzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 10c53c7d Table: 6920004a DAC: 00000015
Process swapper/0 (pid: 0, stack limit = 0x80db0238)
Stack: (0x80db1e98 to 0x80db2000)
1e80: d2234010 8006907c
1ea0: 0000004b ee71da00 d8009900 d800995c d8f2dec0 f4a00100 06f5bb01 0000000d
1ec0: 80db0000 800691e8 d8009900 d800995c 00000000 8006c02c 8006bfa8 0000004b
1ee0: 0000004b 800687f4 80dace54 8000ed4c f4a0010c 80db8970 80db1f18 8000856c
1f00: 00000009 8049c19c 000d0013 ffffffff 80db1f4c 80012240 80db1f60 3b9aca00
1f20: 06f86934 0000000d 80dbe1c8 80dbe1c8 ee71e0d0 00000000 06f5bb01 0000000d
1f40: 80db0000 00000000 00000017 80db1f60 00000009 8049c19c 000d0013 ffffffff
1f60: 06f86934 0000000d 80dc4a54 ee71e0d0 80db8574 ee71e0d0 00000000 00000000
1f80: 00000000 80e797f8 80dbe1c8 8049c2e0 00000000 80db0000 80db8574 806fe48c
1fa0: 80db0038 80e1f13d 80e1f13d 8000f07c 00000000 8006876c ffffffff 80d52b10
1fc0: ffffffff ffffffff 80d5258c 00000000 00000000 80d9ef30 00000000 10c53c7d
1fe0: 80db84fc 80d9ef2c 80dbcb80 1000406a 412fc09a 10008074 00000000 00000000
[<8040eed8>] (usb_hcd_irq) from [<8006907c>] (handle_irq_event_percpu+0x50/0x180)
[<8006907c>] (handle_irq_event_percpu) from [<800691e8>] (handle_irq_event+0x3c/0x5c)
[<800691e8>] (handle_irq_event) from [<8006c02c>] (handle_fasteoi_irq+0x84/0x14c)
[<8006c02c>] (handle_fasteoi_irq) from [<800687f4>] (generic_handle_irq+0x2c/0x3c)
[<800687f4>] (generic_handle_irq) from [<8000ed4c>] (handle_IRQ+0x40/0x90)
[<8000ed4c>] (handle_IRQ) from [<8000856c>] (gic_handle_irq+0x2c/0x5c)
[<8000856c>] (gic_handle_irq) from [<80012240>] (__irq_svc+0x40/0x70)
Exception stack(0x80db1f18 to 0x80db1f60)
1f00: 80db1f60 3b9aca00
1f20: 06f86934 0000000d 80dbe1c8 80dbe1c8 ee71e0d0 00000000 06f5bb01 0000000d
1f40: 80db0000 00000000 00000017 80db1f60 00000009 8049c19c 000d0013 ffffffff
[<80012240>] (__irq_svc) from [<8049c19c>] (cpuidle_enter_state+0x54/0xe4)
[<8049c19c>] (cpuidle_enter_state) from [<8049c2e0>] (cpuidle_idle_call+0xb4/0x14c)
[<8049c2e0>] (cpuidle_idle_call) from [<8000f07c>] (arch_cpu_idle+0x8/0x44)
[<8000f07c>] (arch_cpu_idle) from [<8006876c>] (cpu_startup_entry+0x100/0x14c)
[<8006876c>] (cpu_startup_entry) from [<80d52b10>] (start_kernel+0x350/0x35c)
Code: 11a002a0 03a00001 e12fff1e e92d4008 (e59130b0)
--[ end trace 1160f590a7b228b4 ]--
Kernel panic - not syncing: Fatal exception in interrupt
CPU2: stopping
CPU: 2 PID: 1483 Comm: modprobe Tainted: G D W 3.14.38-usb-host-otg-02047-ga4dec77 #13
[<80014a68>] (unwind_backtrace) from [<80011758>] (show_stack+0x10/0x14)
[<80011758>] (show_stack) from [<806f5fe8>] (dump_stack+0x7c/0xbc)
[<806f5fe8>] (dump_stack) from [<800139f0>] (handle_IPI+0x144/0x158)
[<800139f0>] (handle_IPI) from [<80008598>] (gic_handle_irq+0x58/0x5c)
[<80008598>] (gic_handle_irq) from [<80012240>] (__irq_svc+0x40/0x70)
Exception stack(0xd96c5dc0 to 0xd96c5e08)
5dc0: d800995c 0000004b 00000000 00072004 d8f2dec0 d8009900 d800995c 0000004b
5de0: d800995c a00f0013 00000000 010f2280 fffffffa d96c5e08 00000000 8006926c
5e00: 000f0013 ffffffff
[<80012240>] (__irq_svc) from [<8006926c>] (synchronize_irq+0x18/0xa8)
[<8006926c>] (synchronize_irq) from [<800696dc>] (__free_irq+0xfc/0x1c4)
[<800696dc>] (__free_irq) from [<80069838>] (free_irq+0x4c/0xa4)
[<80069838>] (free_irq) from [<8034b760>] (release_nodes+0x16c/0x1cc)
[<8034b760>] (release_nodes) from [<803487ec>] (__device_release_driver+0x78/0xcc)
[<803487ec>] (__device_release_driver) from [<8034885c>] (device_release_driver+0x1c/0x28)
[<8034885c>] (device_release_driver) from [<8034827c>] (bus_remove_device+0xdc/0x108)
[<8034827c>] (bus_remove_device) from [<80345788>] (device_del+0x100/0x1a4)
[<80345788>] (device_del) from [<8034a218>] (platform_device_del+0x18/0x9c)
[<8034a218>] (platform_device_del) from [<8034a2a8>] (platform_device_unregister+0xc/0x20)
[<8034a2a8>] (platform_device_unregister) from [<7f61932c>] (ci_hdrc_remove_device+0xc/0x20 [ci_hdrc])
[<7f61932c>] (ci_hdrc_remove_device [ci_hdrc]) from [<7f631260>] (ci_hdrc_imx_remove+0x2c/0xdc [ci_hdrc_imx])
[<7f631260>] (ci_hdrc_imx_remove [ci_hdrc_imx]) from [<8034a350>] (platform_drv_remove+0x18/0x30)
[<8034a350>] (platform_drv_remove) from [<803487e4>] (__device_release_driver+0x70/0xcc)
[<803487e4>] (__device_release_driver) from [<80348ef4>] (driver_detach+0xac/0xb0)
[<80348ef4>] (driver_detach) from [<803484e4>] (bus_remove_driver+0x4c/0xa0)
[<803484e4>] (bus_remove_driver) from [<80084158>] (SyS_delete_module+0x11c/0x17c)
[<80084158>] (SyS_delete_module) from [<8000e460>] (ret_fast_syscall+0x0/0x30)
CPU3: stopping
CPU: 3 PID: 0 Comm: swapper/3 Tainted: G D W 3.14.38-usb-host-otg-02047-ga4dec77 #13
[<80014a68>] (unwind_backtrace) from [<80011758>] (show_stack+0x10/0x14)
[<80011758>] (show_stack) from [<806f5fe8>] (dump_stack+0x7c/0xbc)
[<806f5fe8>] (dump_stack) from [<800139f0>] (handle_IPI+0x144/0x158)
[<800139f0>] (handle_IPI) from [<80008598>] (gic_handle_irq+0x58/0x5c)
[<80008598>] (gic_handle_irq) from [<80012240>] (__irq_svc+0x40/0x70)
Exception stack(0xd80b1f50 to 0xd80b1f98)
1f40: d80b1f98 3b9aca00 256aed09 0000000d
1f60: 80dbe1c8 80dbe1c8 ee7360d0 00000000 25477984 0000000d d80b0000 00000000
1f80: 00000017 d80b1f98 00000009 8049c19c 00070013 ffffffff
[<80012240>] (__irq_svc) from [<8049c19c>] (cpuidle_enter_state+0x54/0xe4)
[<8049c19c>] (cpuidle_enter_state) from [<8049c2e0>] (cpuidle_idle_call+0xb4/0x14c)
[<8049c2e0>] (cpuidle_idle_call) from [<8000f07c>] (arch_cpu_idle+0x8/0x44)
[<8000f07c>] (arch_cpu_idle) from [<8006876c>] (cpu_startup_entry+0x100/0x14c)
[<8006876c>] (cpu_startup_entry) from [<10008624>] (0x10008624)
CPU1: stopping
Signed-off-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Li Jun <jun.li@freescale.com>
(cherry picked from commit 402f2d38e22007e931dc3dd52a69c0fed88452bf)
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/chipidea/host.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 8d92d9bf1bf3..b4d87c6c7869 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -273,7 +273,10 @@ done: static irqreturn_t host_irq(struct ci_hdrc *ci) { - return usb_hcd_irq(ci->irq, ci->hcd); + if (ci->hcd) + return usb_hcd_irq(ci->irq, ci->hcd); + else + return IRQ_NONE; } static int host_start(struct ci_hdrc *ci) @@ -469,8 +472,11 @@ static void ci_hdrc_host_resume(struct ci_hdrc *ci, bool power_lost) void ci_hdrc_host_destroy(struct ci_hdrc *ci) { - if (ci->role == CI_ROLE_HOST && ci->hcd) + if (ci->role == CI_ROLE_HOST && ci->hcd) { + disable_irq_nosync(ci->irq); host_stop(ci); + enable_irq(ci->irq); + } } static int ci_ehci_bus_suspend(struct usb_hcd *hcd) |