patch "usb: xhci: Fix panic if disconnect" added to usb-linus
Subsystems (3)
This is a note to let you know that I've just added the patch titled
usb: xhci: Fix panic if disconnect
to my usb git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
Quoted 1 line
From
88716a93766b8f095cdef37a8e8f2c93aa233b21Mon Sep 17 00:00:00 2001
From: Jim Lin <[email protected]>
Date: Tue, 16 Aug 2016 10:18:05 +0300
Subject: usb: xhci: Fix panic if disconnect
After a device is disconnected, xhci_stop_device() will be invoked in xhci_bus_suspend().
Also the "disconnect" IRQ will have ISR to invoke xhci_free_virt_device() in this sequence.xhci_irq -> xhci_handle_event -> handle_cmd_completion -> xhci_handle_cmd_disable_slot -> xhci_free_virt_device
If xhci->devs[slot_id] has been assigned to NULL in xhci_free_virt_device(), then virt_dev->eps[i].ring in xhci_stop_device() may point to an invlid address to cause kernel panic.
virt_dev = xhci->devs[slot_id];
:
if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue)
[] Unable to handle kernel paging request at virtual address 00001a68 [] pgd=ffffffc001430000
[] [00001a68] *pgd=000000013c807003, *pud=000000013c807003, *pmd=000000013c808003, *pte=0000000000000000
[] Internal error: Oops: 96000006 [#1] PREEMPT SMP
[] CPU: 0 PID: 39 Comm: kworker/0:1 Tainted: G U
[] Workqueue: pm pm_runtime_work
[] task: ffffffc0bc0e0bc0 ti: ffffffc0bc0ec000 task.ti:ffffffc0bc0ec000
[] PC is at xhci_stop_device.constprop.11+0xb4/0x1a4
This issue is found when running with realtek ethernet device (0bda:8153).
--- drivers/usb/host/xhci-hub.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/host/xhci-hub.c +3 -0
@@ -386,6 +386,9 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) ret =0 ; virt_dev = xhci->devs[slot_id]; +if (!virt_dev) +return -ENODEV ; + cmd =xhci_alloc_command (xhci, false, true,GFP_NOIO );if (!cmd) {xhci_dbg (xhci,"Couldn't allocate command structure.\n" );
Signature · 1 line
2.9.3