1 From f5cccf49428447dfbc9edb7a04bb8fc316269781 Mon Sep 17 00:00:00 2001
2 From: Guenter Roeck <linux@roeck-us.net>
3 Date: Mon, 20 Mar 2017 14:30:50 -0700
4 Subject: usb: hub: Do not attempt to autosuspend disconnected devices
6 From: Guenter Roeck <linux@roeck-us.net>
8 commit f5cccf49428447dfbc9edb7a04bb8fc316269781 upstream.
10 While running a bind/unbind stress test with the dwc3 usb driver on rk3399,
11 the following crash was observed.
13 Unable to handle kernel NULL pointer dereference at virtual address 00000218
14 pgd = ffffffc00165f000
15 [00000218] *pgd=000000000174f003, *pud=000000000174f003,
16 *pmd=0000000001750003, *pte=00e8000001751713
17 Internal error: Oops: 96000005 [#1] PREEMPT SMP
18 Modules linked in: uinput uvcvideo videobuf2_vmalloc cmac
19 ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat rfcomm
20 xt_mark fuse bridge stp llc zram btusb btrtl btbcm btintel bluetooth
21 ip6table_filter mwifiex_pcie mwifiex cfg80211 cdc_ether usbnet r8152 mii joydev
22 snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device ppp_async
24 CPU: 1 PID: 29814 Comm: kworker/1:1 Not tainted 4.4.52 #507
25 Hardware name: Google Kevin (DT)
26 Workqueue: pm pm_runtime_work
27 task: ffffffc0ac540000 ti: ffffffc0af4d4000 task.ti: ffffffc0af4d4000
28 PC is at autosuspend_check+0x74/0x174
29 LR is at autosuspend_check+0x70/0x174
32 [<ffffffc00080dcc0>] autosuspend_check+0x74/0x174
33 [<ffffffc000810500>] usb_runtime_idle+0x20/0x40
34 [<ffffffc000785ae0>] __rpm_callback+0x48/0x7c
35 [<ffffffc000786af0>] rpm_idle+0x1e8/0x498
36 [<ffffffc000787cdc>] pm_runtime_work+0x88/0xcc
37 [<ffffffc000249bb8>] process_one_work+0x390/0x6b8
38 [<ffffffc00024abcc>] worker_thread+0x480/0x610
39 [<ffffffc000251a80>] kthread+0x164/0x178
40 [<ffffffc0002045d0>] ret_from_fork+0x10/0x40
44 (gdb) l *0xffffffc00080dcc0
45 0xffffffc00080dcc0 is in autosuspend_check
46 (drivers/usb/core/driver.c:1778).
47 1773 /* We don't need to check interfaces that are
48 1774 * disabled for runtime PM. Either they are unbound
49 1775 * or else their drivers don't support autosuspend
50 1776 * and so they are permanently active.
52 1778 if (intf->dev.power.disable_depth)
54 1780 if (atomic_read(&intf->dev.power.usage_count) > 0)
56 1782 w |= intf->needs_remote_wakeup;
58 Code analysis shows that intf is set to NULL in usb_disable_device() prior
59 to setting actconfig to NULL. At the same time, usb_runtime_idle() does not
60 lock the usb device, and neither does any of the functions in the
61 traceback. This means that there is no protection against a race condition
62 where usb_disable_device() is removing dev->actconfig->interface[] pointers
63 while those are being accessed from autosuspend_check().
65 To solve the problem, synchronize and validate device state between
66 autosuspend_check() and usb_disconnect().
68 Acked-by: Alan Stern <stern@rowland.harvard.edu>
69 Signed-off-by: Guenter Roeck <linux@roeck-us.net>
70 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
73 drivers/usb/core/driver.c | 3 +++
74 drivers/usb/core/hub.c | 6 ++++++
75 2 files changed, 9 insertions(+)
77 --- a/drivers/usb/core/driver.c
78 +++ b/drivers/usb/core/driver.c
79 @@ -1781,6 +1781,9 @@ static int autosuspend_check(struct usb_
81 struct usb_interface *intf;
83 + if (udev->state == USB_STATE_NOTATTACHED)
86 /* Fail if autosuspend is disabled, or any interfaces are in use, or
87 * any interface drivers require remote wakeup but it isn't available.
89 --- a/drivers/usb/core/hub.c
90 +++ b/drivers/usb/core/hub.c
91 @@ -2087,6 +2087,12 @@ void usb_disconnect(struct usb_device **
92 dev_info(&udev->dev, "USB disconnect, device number %d\n",
96 + * Ensure that the pm runtime code knows that the USB device
97 + * is in the process of being disconnected.
99 + pm_runtime_barrier(&udev->dev);
101 usb_lock_device(udev);
103 hub_disconnect_children(udev);