mirror of https://github.com/torvalds/linux.git
Avichal Rakesh reported a kernel panic that occurred when the UVC
gadget driver was removed from a gadget's configuration. The panic
involves a somewhat complicated interaction between the kernel driver
and a userspace component (as described in the Link tag below), but
the analysis did make one thing clear: The Gadget core should
accomodate gadget drivers calling usb_gadget_deactivate() as part of
their unbind procedure.
Currently this doesn't work. gadget_unbind_driver() calls
driver->unbind() while holding the udc->connect_lock mutex, and
usb_gadget_deactivate() attempts to acquire that mutex, which will
result in a deadlock.
The simple fix is for gadget_unbind_driver() to release the mutex when
invoking the ->unbind() callback. There is no particular reason for
it to be holding the mutex at that time, and the mutex isn't held
while the ->bind() callback is invoked. So we'll drop the mutex
before performing the unbind callback and reacquire it afterward.
We'll also add a couple of comments to usb_gadget_activate() and
usb_gadget_deactivate(). Because they run in process context they
must not be called from a gadget driver's ->disconnect() callback,
which (according to the kerneldoc for struct usb_gadget_driver in
include/linux/usb/gadget.h) may run in interrupt context. This may
help prevent similar bugs from arising in the future.
Reported-and-tested-by: Avichal Rakesh <arakesh@google.com>
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Fixes:
|
||
|---|---|---|
| .. | ||
| aspeed-vhub | ||
| bdc | ||
| cdns2 | ||
| Kconfig | ||
| Makefile | ||
| amd5536udc.h | ||
| amd5536udc_pci.c | ||
| aspeed_udc.c | ||
| at91_udc.c | ||
| at91_udc.h | ||
| atmel_usba_udc.c | ||
| atmel_usba_udc.h | ||
| bcm63xx_udc.c | ||
| core.c | ||
| dummy_hcd.c | ||
| fsl_qe_udc.c | ||
| fsl_qe_udc.h | ||
| fsl_udc_core.c | ||
| fsl_usb2_udc.h | ||
| fusb300_udc.c | ||
| fusb300_udc.h | ||
| goku_udc.c | ||
| goku_udc.h | ||
| gr_udc.c | ||
| gr_udc.h | ||
| lpc32xx_udc.c | ||
| m66592-udc.c | ||
| m66592-udc.h | ||
| max3420_udc.c | ||
| mv_u3d.h | ||
| mv_u3d_core.c | ||
| mv_udc.h | ||
| mv_udc_core.c | ||
| net2272.c | ||
| net2272.h | ||
| net2280.c | ||
| net2280.h | ||
| omap_udc.c | ||
| omap_udc.h | ||
| pch_udc.c | ||
| pxa25x_udc.c | ||
| pxa25x_udc.h | ||
| pxa27x_udc.c | ||
| pxa27x_udc.h | ||
| r8a66597-udc.c | ||
| r8a66597-udc.h | ||
| renesas_usb3.c | ||
| renesas_usbf.c | ||
| rzv2m_usb3drd.c | ||
| snps_udc_core.c | ||
| snps_udc_plat.c | ||
| tegra-xudc.c | ||
| trace.c | ||
| trace.h | ||
| udc-xilinx.c | ||