| From 331de00a64e5027365145bdf51da27b9ce15dfd5 Mon Sep 17 00:00:00 2001 |
| From: Sergio Aguirre <sergio.a.aguirre.rodriguez@intel.com> |
| Date: Thu, 4 Apr 2013 10:32:13 -0700 |
| Subject: xhci-mem: init list heads at the beginning of init |
| |
| From: Sergio Aguirre <sergio.a.aguirre.rodriguez@intel.com> |
| |
| commit 331de00a64e5027365145bdf51da27b9ce15dfd5 upstream. |
| |
| It is possible that we fail on xhci_mem_init, just before doing |
| the INIT_LIST_HEAD, and calling xhci_mem_cleanup. |
| |
| Problem is that, the list_for_each_entry_safe macro, assumes |
| list heads are initialized (not NULL), and dereferences their 'next' |
| pointer, causing a kernel panic if this is not yet initialized. |
| |
| Let's protect from that by moving inits to the beginning. |
| |
| This patch should be backported to kernels as old as 3.2, that |
| contain the commit 9574323c39d1f8359a04843075d89c9f32d8b7e6 "xHCI: test |
| USB2 software LPM". |
| |
| Signed-off-by: Sergio Aguirre <sergio.a.aguirre.rodriguez@intel.com> |
| Acked-by: David Cohen <david.a.cohen@intel.com> |
| Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/host/xhci-mem.c | 6 +++--- |
| 1 file changed, 3 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/usb/host/xhci-mem.c |
| +++ b/drivers/usb/host/xhci-mem.c |
| @@ -2256,6 +2256,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, |
| u32 page_size, temp; |
| int i; |
| |
| + INIT_LIST_HEAD(&xhci->lpm_failed_devs); |
| + INIT_LIST_HEAD(&xhci->cancel_cmd_list); |
| + |
| page_size = xhci_readl(xhci, &xhci->op_regs->page_size); |
| xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size); |
| for (i = 0; i < 16; i++) { |
| @@ -2334,7 +2337,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, |
| xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags); |
| if (!xhci->cmd_ring) |
| goto fail; |
| - INIT_LIST_HEAD(&xhci->cancel_cmd_list); |
| xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring); |
| xhci_dbg(xhci, "First segment DMA is 0x%llx\n", |
| (unsigned long long)xhci->cmd_ring->first_seg->dma); |
| @@ -2445,8 +2447,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, |
| if (xhci_setup_port_arrays(xhci, flags)) |
| goto fail; |
| |
| - INIT_LIST_HEAD(&xhci->lpm_failed_devs); |
| - |
| /* Enable USB 3.0 device notifications for function remote wake, which |
| * is necessary for allowing USB 3.0 devices to do remote wakeup from |
| * U3 (device suspend). |