There may be a race condition if f_fs calls unregister_gadget_item in
ffs_closed() when unregister_gadget is called by UDC store at the same time.
this leads to a kernel NULL pointer dereference:
[ 310.644928] Unable to handle kernel NULL pointer dereference at virtual address
00000004
[ 310.645053] init: Service 'adbd' is being killed...
[ 310.658938] pgd =
c9528000
[ 310.662515] [
00000004] *pgd=
19451831, *pte=
00000000, *ppte=
00000000
[ 310.669702] Internal error: Oops: 817 [#1] PREEMPT SMP ARM
[ 310.675211] Modules linked in:
[ 310.678294] CPU: 0 PID: 1537 Comm: ->transport Not tainted
4.1.15-03725-g793404c #2
[ 310.685958] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[ 310.692493] task:
c8e24200 ti:
c945e000 task.ti:
c945e000
[ 310.697911] PC is at usb_gadget_unregister_driver+0xb4/0xd0
[ 310.703502] LR is at __mutex_lock_slowpath+0x10c/0x16c
[ 310.708648] pc : [<
c075efc0>] lr : [<
c0bfb0bc>] psr:
600f0113
<snip..>
[ 311.565585] [<
c075efc0>] (usb_gadget_unregister_driver) from [<
c075e2b8>] (unregister_gadget_item+0x1c/0x34)
[ 311.575426] [<
c075e2b8>] (unregister_gadget_item) from [<
c076fcc8>] (ffs_closed+0x8c/0x9c)
[ 311.583702] [<
c076fcc8>] (ffs_closed) from [<
c07736b8>] (ffs_data_reset+0xc/0xa0)
[ 311.591194] [<
c07736b8>] (ffs_data_reset) from [<
c07738ac>] (ffs_data_closed+0x90/0xd0)
[ 311.599208] [<
c07738ac>] (ffs_data_closed) from [<
c07738f8>] (ffs_ep0_release+0xc/0x14)
[ 311.607224] [<
c07738f8>] (ffs_ep0_release) from [<
c023e030>] (__fput+0x80/0x1d0)
[ 311.614635] [<
c023e030>] (__fput) from [<
c014e688>] (task_work_run+0xb0/0xe8)
[ 311.621788] [<
c014e688>] (task_work_run) from [<
c010afdc>] (do_work_pending+0x7c/0xa4)
[ 311.629718] [<
c010afdc>] (do_work_pending) from [<
c010770c>] (work_pending+0xc/0x20)
for functions using functionFS, i.e. android adbd will close /dev/usb-ffs/adb/ep0
when usb IO thread fails, but switch adb from on to off also triggers write
"none" > UDC. These 2 operations both call unregister_gadget, which will lead
to the panic above.
add a mutex before calling unregister_gadget for api used in f_fs.
Signed-off-by: Winter Wang <wente.wang@nxp.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>