linux/drivers/usb/host
Gabriel Krisman Bertazi 27a41a83ec xhci: Cleanup only when releasing primary hcd
Under stress occasions some TI devices might not return early when
reading the status register during the quirk invocation of xhci_irq made
by usb_hcd_pci_remove.  This means that instead of returning, we end up
handling this interruption in the middle of a shutdown.  Since
xhci->event_ring has already been freed in xhci_mem_cleanup, we end up
accessing freed memory, causing the Oops below.

commit 8c24d6d7b0 ("usb: xhci: stop everything on the first call to
xhci_stop") is the one that changed the instant in which we clean up the
event queue when stopping a device.  Before, we didn't call
xhci_mem_cleanup at the first time xhci_stop is executed (for the shared
HCD), instead, we only did it after the invocation for the primary HCD,
much later at the removal path.  The code flow for this oops looks like
this:

xhci_pci_remove()
	usb_remove_hcd(xhci->shared)
	        xhci_stop(xhci->shared)
 			xhci_halt()
			xhci_mem_cleanup(xhci);  // Free the event_queue
	usb_hcd_pci_remove(primary)
		xhci_irq()  // Access the event_queue if STS_EINT is set. Crash.
		xhci_stop()
			xhci_halt()
			// return early

The fix modifies xhci_stop to only cleanup the xhci data when releasing
the primary HCD.  This way, we still have the event_queue configured
when invoking xhci_irq.  We still halt the device on the first call to
xhci_stop, though.

I could reproduce this issue several times on the mainline kernel by
doing a bind-unbind stress test with a specific storage gadget attached.
I also ran the same test over-night with my patch applied and didn't
observe the issue anymore.

[  113.334124] Unable to handle kernel paging request for data at address 0x00000028
[  113.335514] Faulting instruction address: 0xd00000000d4f767c
[  113.336839] Oops: Kernel access of bad area, sig: 11 [#1]
[  113.338214] SMP NR_CPUS=1024 NUMA PowerNV

[c000000efe47ba90] c000000000720850 usb_hcd_irq+0x50/0x80
[c000000efe47bac0] c00000000073d328 usb_hcd_pci_remove+0x68/0x1f0
[c000000efe47bb00] d00000000daf0128 xhci_pci_remove+0x78/0xb0
[xhci_pci]
[c000000efe47bb30] c00000000055cf70 pci_device_remove+0x70/0x110
[c000000efe47bb70] c00000000061c6bc __device_release_driver+0xbc/0x190
[c000000efe47bba0] c00000000061c7d0 device_release_driver+0x40/0x70
[c000000efe47bbd0] c000000000619510 unbind_store+0x120/0x150
[c000000efe47bc20] c0000000006183c4 drv_attr_store+0x64/0xa0
[c000000efe47bc60] c00000000039f1d0 sysfs_kf_write+0x80/0xb0
[c000000efe47bca0] c00000000039e14c kernfs_fop_write+0x18c/0x1f0
[c000000efe47bcf0] c0000000002e962c __vfs_write+0x6c/0x190
[c000000efe47bd90] c0000000002eab40 vfs_write+0xc0/0x200
[c000000efe47bde0] c0000000002ec85c SyS_write+0x6c/0x110
[c000000efe47be30] c000000000009260 system_call+0x38/0x108

Signed-off-by: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com>
Cc: Roger Quadros <rogerq@ti.com>
Cc: joel@jms.id.au
Cc: stable@vger.kernel.org
Reviewed-by: Roger Quadros <rogerq@ti.com>
Cc: <stable@vger.kernel.org> #v4.3+
Tested-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-06-01 14:55:01 -07:00
..
whci usb: hcd: do not call whc_clean_up on wch_init call failure 2016-04-26 16:11:22 -07:00
bcma-hcd.c USB: bcma: use simpler devm helper for getting vcc GPIO 2016-04-26 16:11:22 -07:00
ehci-atmel.c usb: ehci-atmel: use __maybe_unused to hide pm functions 2016-03-03 20:37:41 -08:00
ehci-dbg.c USB: EHCI: make all debugging depend on CONFIG_DYNAMIC_DEBUG 2016-04-29 15:31:30 -07:00
ehci-exynos.c usb/host/: const data must use __initconst not __initdata 2016-04-28 12:35:36 -07:00
ehci-fsl.c drivers/usb/host/fsl: Port USB EHCI host driver for LS102xA 2016-01-24 20:37:47 -08:00
ehci-fsl.h drivers: usb: fsl: Define usb control register mask for w1c bits 2015-07-22 16:44:35 -07:00
ehci-grlib.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ehci-hcd.c USB: EHCI: fix compiler warning introduced by commit 2a40f32454 2016-02-04 11:27:11 -08:00
ehci-hub.c USB: EHCI: fix compiler warning introduced by commit 2a40f32454 2016-02-04 11:27:11 -08:00
ehci-mem.c USB-EHCI: Delete unnecessary checks before the function call "dma_pool_destroy" 2015-12-01 14:26:33 -08:00
ehci-msm.c usb/host/: const data must use __initconst not __initdata 2016-04-28 12:35:36 -07:00
ehci-mv.c host: ehci-mv: remove duplicate check on resource 2014-11-07 09:01:50 -08:00
ehci-mxc.c host: ehci-mxc: remove duplicate check on resource 2014-11-07 09:01:50 -08:00
ehci-omap.c usb/host/: const data must use __initconst not __initdata 2016-04-28 12:35:36 -07:00
ehci-orion.c usb: ehci-orion: fix probe for !GENERIC_PHY 2015-10-04 10:45:08 +01:00
ehci-pci.c ehci-hcd: Disable memory-write-invalidate when the driver is removed 2016-01-24 20:51:34 -08:00
ehci-platform.c USB: host: use to_platform_device 2016-01-24 21:00:33 -08:00
ehci-pmcmsp.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ehci-ppc-of.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ehci-ps3.c
ehci-q.c USB: EHCI: improvements to unlink_empty_async_suspended() 2016-02-03 13:14:52 -08:00
ehci-sched.c usb: host: ehci-sched: remove unnecessary braces 2016-02-03 13:44:05 -08:00
ehci-sead3.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ehci-sh.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ehci-spear.c usb/host/: const data must use __initconst not __initdata 2016-04-28 12:35:36 -07:00
ehci-st.c USB: host: use to_platform_device 2016-01-24 21:00:33 -08:00
ehci-sysfs.c usb: host: ehci-sys: delete useless bus_to_hcd conversion 2015-08-18 10:05:23 -07:00
ehci-tegra.c USB: ehci-tegra: fix inefficient copy of unaligned buffers 2015-05-08 01:43:44 +02:00
ehci-tilegx.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ehci-timer.c USB: EHCI: add a delay when unlinking an active QH 2016-02-03 13:14:52 -08:00
ehci-w90x900.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
ehci-xilinx-of.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ehci.h usb: host: unhide suspend/resume declarations 2016-03-03 20:37:41 -08:00
fhci-dbg.c
fhci-hcd.c QE: Move QE from arch/powerpc to drivers/soc 2015-12-22 17:12:56 -06:00
fhci-hub.c QE: Move QE from arch/powerpc to drivers/soc 2015-12-22 17:12:56 -06:00
fhci-mem.c
fhci-q.c
fhci-sched.c USB: FHCI: avoid redundant condition 2016-05-09 13:08:46 +02:00
fhci-tds.c usb: whci: fhci: remove comparison to bool 2015-12-04 08:25:58 -08:00
fhci.h QE: Move QE from arch/powerpc to drivers/soc 2015-12-22 17:12:56 -06:00
fotg210-hcd.c usb/host/fotg210: remove dead code in create_sysfs_files 2016-05-09 13:08:46 +02:00
fotg210.h usb/host/fotg210: Fix coding style issues 2015-10-16 23:46:22 -07:00
fsl-mph-dr-of.c drivers/usb/host: fsl: Set DMA_MASK of usb platform device 2016-01-24 20:37:47 -08:00
hwa-hc.c
imx21-dbg.c
imx21-hcd.c imx21-hcd: use USB_DT_HUB 2015-04-03 19:03:18 +02:00
imx21-hcd.h
isp116x-hcd.c USB: isp116x-hcd.c: move assignment out of if () block 2015-05-10 16:01:11 +02:00
isp116x.h
isp1362-hcd.c isp1362-hcd: use USB_DT_HUB 2015-04-03 19:03:18 +02:00
isp1362.h
Kconfig USB patches for 4.7-rc1 2016-05-20 21:12:25 -07:00
Makefile usb: xhci: Add NVIDIA Tegra XUSB controller driver 2016-04-29 16:48:58 +02:00
max3421-hcd.c usb: host: max3421-hcd: use list_for_each_entry* 2016-01-24 20:55:33 -08:00
ohci-at91.c This is the bulk of GPIO changes for kernel v4.6: 2016-03-17 21:05:32 -07:00
ohci-da8xx.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ohci-dbg.c USB: ohci-dbg.c: move assignment out of if () block 2015-05-10 16:01:11 +02:00
ohci-exynos.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
ohci-hcd.c USB: ohci-jz4740: Remove obsolete driver 2016-05-13 19:10:20 +02:00
ohci-hub.c ohci-hub: use USB_DT_HUB 2015-04-03 19:03:17 +02:00
ohci-mem.c
ohci-nxp.c usb: ohci: nxp: remove USB PLL and USB OTG clock management 2016-03-03 20:38:53 -08:00
ohci-omap3.c
ohci-omap.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
ohci-pci.c
ohci-platform.c USB: host: use to_platform_device 2016-01-24 21:00:33 -08:00
ohci-ppc-of.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ohci-ps3.c
ohci-pxa27x.c usb: host: ohci-pxa27x: propagate the irq error code 2016-02-14 17:06:43 -08:00
ohci-q.c USB: OHCI: Fix race between ED unlink and URB submission 2015-07-22 14:46:50 -07:00
ohci-s3c2410.c ohci-s3c2410: use HUB_CHAR_* 2015-01-25 21:01:13 +08:00
ohci-sa1111.c
ohci-sm501.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ohci-spear.c usb: host: ohci-spear: Fix module autoload for OF platform driver 2015-10-04 10:51:58 +01:00
ohci-st.c USB: host: use to_platform_device 2016-01-24 21:00:33 -08:00
ohci-tilegx.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
ohci-tmio.c USB: OHCI: fix bad #define in ohci-tmio.c 2015-07-22 14:49:42 -07:00
ohci.h usb: host: unhide suspend/resume declarations 2016-03-03 20:37:41 -08:00
oxu210hp-hcd.c usb: host: oxu210hp-hcd: use list_for_each_entry_safe 2016-01-24 20:55:33 -08:00
oxu210hp.h
pci-quirks.c usb: host: pci_quirks: fix memory leak, by adding iounmap 2016-02-14 17:21:09 -08:00
pci-quirks.h
r8a66597-hcd.c usb: r8a66597: add locking to r8a66597_check_detect_child 2016-02-06 21:55:57 -08:00
r8a66597.h
sl811_cs.c
sl811-hcd.c usb: generic resume timeout for v4.1 2015-04-10 13:45:27 +02:00
sl811.h
ssb-hcd.c USB: ssb: use devm_kzalloc 2015-06-08 14:26:22 -07:00
u132-hcd.c usb: host: u132-hcd: use list_for_each_entry 2016-01-24 20:55:33 -08:00
uhci-debug.c new helpers: no_seek_end_llseek{,_size}() 2015-12-23 10:41:31 -05:00
uhci-grlib.c usb: host: drop owner assignment from platform_drivers 2015-01-09 12:31:53 -08:00
uhci-hcd.c
uhci-hcd.h
uhci-hub.c usb: generic resume timeout for v4.1 2015-04-10 13:45:27 +02:00
uhci-pci.c
uhci-platform.c usb: host: uhci-platform: Fix module autoload for OF platform driver 2015-10-04 10:51:58 +01:00
uhci-q.c usb : replace dma_pool_alloc and memset with dma_pool_zalloc 2015-12-01 14:26:33 -08:00
xhci-dbg.c xhci: Read and parse new xhci 1.1 capability register 2015-10-04 10:34:17 +01:00
xhci-ext-caps.h xhci: harden xhci_find_next_ext_cap against device removal 2016-02-04 17:00:10 -08:00
xhci-hub.c xhci: USB 3.1 add default Speed Attributes to SuperSpeedPlus device capability 2016-02-03 13:20:54 -08:00
xhci-mem.c usb: xhci: fix wild pointers in xhci_mem_cleanup 2016-04-13 11:55:56 -07:00
xhci-mtk-sch.c usb: xhci-mtk: fix bpkts value of LS/HS periodic eps not behind TT 2016-02-03 14:01:47 -08:00
xhci-mtk.c usb: xhci-mtk: use __maybe_unused to hide pm functions 2016-03-03 20:37:41 -08:00
xhci-mtk.h xhci: mediatek: support MTK xHCI host controller 2015-12-01 10:45:51 -08:00
xhci-mvebu.c usb: host: xhci: plat: change type of mvebu init_quirk() 2016-04-26 16:08:02 -07:00
xhci-mvebu.h usb: host: xhci: plat: change type of mvebu init_quirk() 2016-04-26 16:08:02 -07:00
xhci-pci.c xhci: fix 10 second timeout on removal of PCI hotpluggable xhci controllers 2016-04-13 11:55:56 -07:00
xhci-plat.c usb: host: xhci: plat: finally get rid of xhci_plat_type_is() 2016-04-26 16:08:02 -07:00
xhci-plat.h usb: host: xhci: plat: finally get rid of xhci_plat_type_is() 2016-04-26 16:08:02 -07:00
xhci-rcar.c usb: host: xhci: rcar: retire use of xhci_plat_type_is() 2016-04-26 16:08:02 -07:00
xhci-rcar.h usb: host: xhci-plat: add support for the R-Car H3 xHCI controllers 2015-12-01 10:45:51 -08:00
xhci-ring.c xhci: Cleanup only when releasing primary hcd 2016-06-01 14:55:01 -07:00
xhci-tegra.c usb: xhci: tegra: Add Tegra210 support 2016-04-29 16:48:59 +02:00
xhci-trace.c
xhci-trace.h tracing: Add TRACE_SYSTEM_VAR to xhci-hcd 2015-04-07 12:31:55 -04:00
xhci.c xhci: Cleanup only when releasing primary hcd 2016-06-01 14:55:01 -07:00
xhci.h usb: xhci: remove duplicate function xhci_urb_to_transfer_ring 2016-04-26 16:08:02 -07:00