• Peter Chen's avatar
    usb: gadget: core: sync interrupt before unbind the udc · 3c73bc52
    Peter Chen authored
    The threaded interrupt handler may still be called after the
    usb_gadget_disconnect is called, it causes the structures used
    at interrupt handler was freed before it uses, eg the
    usb_request. This issue usually occurs we remove the udc function
    during the transfer. Below is the example when doing stress
    test for android switch function, the EP0's request is freed
    by .unbind (configfs_composite_unbind -> composite_dev_cleanup),
    but the threaded handler accesses this request during handling
    setup packet request.
    
    In fact, there is no protection between unbind the udc
    and udc interrupt handling, so we have to avoid the interrupt
    handler is occurred or scheduled during the .unbind flow.
    
    init: Sending signal 9 to service 'adbd' (pid 18077) process group...
    android_work: did not send uevent (0 0 000000007bec2039)
    libprocessgroup: Successfully killed process cgroup uid 0 pid 18077 in 6ms
    init: Service 'adbd' (pid 18077) received signal 9
    init: Sending signal 9 to service 'adbd' (pid 18077) process group...
    libprocessgroup: Successfully killed process cgroup uid 0 pid 18077 in 0ms
    init: processing action (init.svc.adbd=stopped) from (/init.usb.configfs.rc:14)
    init: Received control message 'start' for 'adbd' from pid: 399 (/vendor/bin/hw/android.hardware.usb@1.
    
    init: starting service 'adbd'...
    read descriptors
    read strings
    Unable to handle kernel read from unreadable memory at virtual address 000000000000002a
    android_work: sent uevent USB_STATE=CONNECTED
    Mem abort info:
      ESR = 0x96000004
      EC = 0x25: DABT (current EL), IL = 32 bits
      SET = 0, FnV = 0
      EA = 0, S1PTW = 0
    Data abort info:
      ISV = 0, ISS = 0x00000004
      CM = 0, WnR = 0
    user pgtable: 4k pages, 48-bit VAs, pgdp=00000000e97f1000
    using random self ethernet address
    [000000000000002a] pgd=0000000000000000
    Internal error: Oops: 96000004 [#1] PREEMPT SMP
    Modules linked in:
    CPU: 0 PID: 232 Comm: irq/68-5b110000 Not tainted 5.4.24-06075-g94a6b52b5815 #92
    Hardware name: Freescale i.MX8QXP MEK (DT)
    pstate: 00400085 (nzcv daIf +PAN -UAO)
    using random host ethernet address
    pc : composite_setup+0x5c/0x1730
    lr : android_setup+0xc0/0x148
    sp : ffff80001349bba0
    x29: ffff80001349bba0 x28: ffff00083a50da00
    x27: ffff8000124e6000 x26: ffff800010177950
    x25: 0000000000000040 x24: ffff000834e18010
    x23: 0000000000000000 x22: 0000000000000000
    x21: ffff00083a50da00 x20: ffff00082e75ec40
    x19: 0000000000000000 x18: 0000000000000000
    x17: 0000000000000000 x16: 0000000000000000
    x15: 0000000000000000 x14: 0000000000000000
    x13: 0000000000000000 x12: 0000000000000001
    x11: ffff80001180fb58 x10: 0000000000000040
    x9 : ffff8000120fc980 x8 : 0000000000000000
    x7 : ffff00083f98df50 x6 : 0000000000000100
    x5 : 00000307e8978431 x4 : ffff800011386788
    x3 : 0000000000000000 x2 : ffff800012342000
    x1 : 0000000000000000 x0 : ffff800010c6d3a0
    Call trace:
     composite_setup+0x5c/0x1730
     android_setup+0xc0/0x148
     cdns3_ep0_delegate_req+0x64/0x90
     cdns3_check_ep0_interrupt_proceed+0x384/0x738
     cdns3_device_thread_irq_handler+0x124/0x6e0
     cdns3_thread_irq+0x94/0xa0
     irq_thread_fn+0x30/0xa0
     irq_thread+0x150/0x248
     kthread+0xfc/0x128
     ret_from_fork+0x10/0x18
    Code: 910e8000 f9400693 12001ed7 79400f79 (3940aa61)
    ---[ end trace c685db37f8773fba ]---
    Kernel panic - not syncing: Fatal exception
    SMP: stopping secondary CPUs
    Kernel Offset: disabled
    CPU features: 0x0002,20002008
    Memory Limit: none
    Rebooting in 5 seconds..
    Reviewed-by: default avatarJun Li <jun.li@nxp.com>
    Signed-off-by: default avatarPeter Chen <peter.chen@nxp.com>
    Signed-off-by: default avatarFelipe Balbi <balbi@kernel.org>
    3c73bc52
gadget.h 34 KB