Patch "USB: dummy-hcd: Fix deadlock caused by disconnect detection" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
USB: dummy-hcd: Fix deadlock caused by disconnect detection
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
usb-dummy-hcd-fix-deadlock-caused-by-disconnect-detection.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
ab219221a5064abfff9f78c323c4a257b16cdb81Mon Sep 17 00:00:00 2001
From: Alan Stern <[email protected]>
Date: Fri, 6 Oct 2017 10:27:44 -0400
Subject: USB: dummy-hcd: Fix deadlock caused by disconnect detection
From: Alan Stern <[email protected]>
commit ab219221a5064abfff9f78c323c4a257b16cdb81 upstream.
The dummy-hcd driver calls the gadget driver's disconnect callback under the wrong conditions. It should invoke the callback when Vbus power is turned off, but instead it does so when the D+ pullup is turned off.
This can cause a deadlock in the composite core when a gadget driver is unregistered:
[ 88.361471] ============================================
[ 88.362014] WARNING: possible recursive locking detected
[ 88.362580] 4.14.0-rc2+ #9 Not tainted
[ 88.363010] --------------------------------------------
[ 88.363561] v4l_id/526 is trying to acquire lock:
[ 88.364062] (&(&cdev->lock)->rlock){....}, at: [<ffffffffa0547e03>] composite_disconnect+0x43/0x100 [libcomposite]
[ 88.365051]
[ 88.365051] but task is already holding lock:
[ 88.365826] (&(&cdev->lock)->rlock){....}, at: [<ffffffffa0547b09>] usb_function_deactivate+0x29/0x80 [libcomposite]
[ 88.366858]
[ 88.366858] other info that might help us debug this:
[ 88.368301] Possible unsafe locking scenario:
[ 88.368301]
[ 88.369304] CPU0
[ 88.369701] ----
[ 88.370101] lock(&(&cdev->lock)->rlock);
[ 88.370623] lock(&(&cdev->lock)->rlock);
[ 88.371145]
[ 88.371145] *** DEADLOCK ***
[ 88.371145]
[ 88.372211] May be due to missing lock nesting notation
[ 88.372211]
[ 88.373191] 2 locks held by v4l_id/526:
[ 88.373715] #0: (&(&cdev->lock)->rlock){....}, at: [<ffffffffa0547b09>] usb_function_deactivate+0x29/0x80 [libcomposite]
[ 88.374814] #1: (&(&dum_hcd->dum->lock)->rlock){....}, at: [<ffffffffa05bd48d>] dummy_pullup+0x7d/0xf0 [dummy_hcd]
[ 88.376289]
[ 88.376289] stack backtrace:
[ 88.377726] CPU: 0 PID: 526 Comm: v4l_id Not tainted 4.14.0-rc2+ #9
[ 88.378557] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
[ 88.379504] Call Trace:
[ 88.380019] dump_stack+0x86/0xc7
[ 88.380605] __lock_acquire+0x841/0x1120
[ 88.381252] lock_acquire+0xd5/0x1c0
[ 88.381865] ? composite_disconnect+0x43/0x100 [libcomposite]
[ 88.382668] _raw_spin_lock_irqsave+0x40/0x54
[ 88.383357] ? composite_disconnect+0x43/0x100 [libcomposite]
[ 88.384290] composite_disconnect+0x43/0x100 [libcomposite]
[ 88.385490] set_link_state+0x2d4/0x3c0 [dummy_hcd]
[ 88.386436] dummy_pullup+0xa7/0xf0 [dummy_hcd]
[ 88.387195] usb_gadget_disconnect+0xd8/0x160 [udc_core]
[ 88.387990] usb_gadget_deactivate+0xd3/0x160 [udc_core]
[ 88.388793] usb_function_deactivate+0x64/0x80 [libcomposite]
[ 88.389628] uvc_function_disconnect+0x1e/0x40 [usb_f_uvc]This patch changes the code to test the port-power status bit rather than the port-connect status bit when deciding whether to isue the callback.
--- drivers/usb/gadget/udc/dummy_hcd.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/usb/gadget/udc/dummy_hcd.c +6 -3
@@ -420,6 +420,7 @@ static void set_link_state_by_speed(strustatic void set_link_state (struct dummy_hcd *dum_hcd) {struct dummy *dum = dum_hcd->dum; +unsigned int power_bit; dum_hcd->active =0 ;if (dum->pullup)
@@ -430,17 +431,19 @@ static void set_link_state(struct dummy_return ;set_link_state_by_speed (dum_hcd); + power_bit = (dummy_hcd_to_hcd (dum_hcd)->speed ==HCD_USB3 ? +USB_SS_PORT_STAT_POWER :USB_PORT_STAT_POWER );if ((dum_hcd->port_status &USB_PORT_STAT_ENABLE ) ==0 || dum_hcd->active) dum_hcd->resuming =0 ;/* Currently !connected or in reset */ -if ((dum_hcd->port_status &USB_PORT_STAT_CONNECTION ) ==0 || +if ((dum_hcd->port_status & power_bit) ==0 || (dum_hcd->port_status &USB_PORT_STAT_RESET ) !=0 ) { -unsigned disconnect =USB_PORT_STAT_CONNECTION & +unsigned int disconnect = power_bit & dum_hcd->old_status & (~dum_hcd->port_status); -unsigned reset =USB_PORT_STAT_RESET & +unsigned int reset =USB_PORT_STAT_RESET & (~dum_hcd->old_status) & dum_hcd->port_status;/* Report reset and disconnect events to the driver */
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/hid-usbhid-fix-out-of-bounds-bug.patch queue-4.4/usb-dummy-hcd-fix-deadlock-caused-by-disconnect-detection.patch