stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] xhci: always handle "Command Ring Stopped" events
       [not found] <1471331886-24617-1-git-send-email-mathias.nyman@linux.intel.com>
@ 2016-08-16  7:18 ` Mathias Nyman
  2016-08-16  7:18 ` [PATCH 3/4] usb: xhci: Fix panic if disconnect Mathias Nyman
  2016-08-16  7:18 ` [PATCH 4/4] xhci: don't dereference a xhci member after removing xhci Mathias Nyman
  2 siblings, 0 replies; 3+ messages in thread
From: Mathias Nyman @ 2016-08-16  7:18 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman, stable

Fix "Command completion event does not match command" errors by always
handling the command ring stopped events.

The command ring stopped event is generated as a result of aborting
or stopping the command ring with a register write. It is not caused
by a command in the command queue, and thus won't have a matching command
in the comman list.

Solve it by handling the command ring stopped event before checking for a
matching command.

In most command time out cases we abort the command ring, and get
a command ring stopped event. The events command pointer will point at
the current command ring dequeue, which in most cases matches the timed
out command in the command list, and no error messages are seen.

If we instead get a command aborted event before the command ring stopped
event, the abort event will increse the command ring dequeue pointer, and
the following command ring stopped events command pointer will point at the
next, not yet queued command. This case triggered the error message

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
CC: <stable@vger.kernel.org>
---
 drivers/usb/host/xhci-ring.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 918e0c7..fe5b70b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1334,12 +1334,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
 
 	cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list);
 
-	if (cmd->command_trb != xhci->cmd_ring->dequeue) {
-		xhci_err(xhci,
-			 "Command completion event does not match command\n");
-		return;
-	}
-
 	del_timer(&xhci->cmd_timer);
 
 	trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event);
@@ -1351,6 +1345,13 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
 		xhci_handle_stopped_cmd_ring(xhci, cmd);
 		return;
 	}
+
+	if (cmd->command_trb != xhci->cmd_ring->dequeue) {
+		xhci_err(xhci,
+			 "Command completion event does not match command\n");
+		return;
+	}
+
 	/*
 	 * Host aborted the command ring, check if the current command was
 	 * supposed to be aborted, otherwise continue normally.
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 3/4] usb: xhci: Fix panic if disconnect
       [not found] <1471331886-24617-1-git-send-email-mathias.nyman@linux.intel.com>
  2016-08-16  7:18 ` [PATCH 1/4] xhci: always handle "Command Ring Stopped" events Mathias Nyman
@ 2016-08-16  7:18 ` Mathias Nyman
  2016-08-16  7:18 ` [PATCH 4/4] xhci: don't dereference a xhci member after removing xhci Mathias Nyman
  2 siblings, 0 replies; 3+ messages in thread
From: Mathias Nyman @ 2016-08-16  7:18 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Jim Lin, stable, Mathias Nyman

From: Jim Lin <jilin@nvidia.com>

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).

Signed-off-by: Jim Lin <jilin@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-hub.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index d61fcc4..730b9fd 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -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");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 4/4] xhci: don't dereference a xhci member after removing xhci
       [not found] <1471331886-24617-1-git-send-email-mathias.nyman@linux.intel.com>
  2016-08-16  7:18 ` [PATCH 1/4] xhci: always handle "Command Ring Stopped" events Mathias Nyman
  2016-08-16  7:18 ` [PATCH 3/4] usb: xhci: Fix panic if disconnect Mathias Nyman
@ 2016-08-16  7:18 ` Mathias Nyman
  2 siblings, 0 replies; 3+ messages in thread
From: Mathias Nyman @ 2016-08-16  7:18 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, Mathias Nyman, stable

Remove the hcd after checking for the xhci last quirks, not before.

This caused a hang on a Alpine Ridge xhci based maching which remove
the whole xhci controller when unplugging the last usb device

CC: <stable@vger.kernel.org>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-pci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 4fd041b..d7b0f97 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -314,11 +314,12 @@ static void xhci_pci_remove(struct pci_dev *dev)
 		usb_remove_hcd(xhci->shared_hcd);
 		usb_put_hcd(xhci->shared_hcd);
 	}
-	usb_hcd_pci_remove(dev);
 
 	/* Workaround for spurious wakeups at shutdown with HSW */
 	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
 		pci_set_power_state(dev, PCI_D3hot);
+
+	usb_hcd_pci_remove(dev);
 }
 
 #ifdef CONFIG_PM
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-08-16  7:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1471331886-24617-1-git-send-email-mathias.nyman@linux.intel.com>
2016-08-16  7:18 ` [PATCH 1/4] xhci: always handle "Command Ring Stopped" events Mathias Nyman
2016-08-16  7:18 ` [PATCH 3/4] usb: xhci: Fix panic if disconnect Mathias Nyman
2016-08-16  7:18 ` [PATCH 4/4] xhci: don't dereference a xhci member after removing xhci Mathias Nyman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).