All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org, Denis Kirjanov <kda@linux-powerpc.org>,
	"Mathias Nyman" <mathias.nyman@linux.intel.com>,
	"Lee, Chiasheng" <chiasheng.lee@intel.com>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Lee, Hou-hsun" <hou-hsun.lee@intel.com>
Subject: [PATCH 3.16 53/63] xhci: fix USB3 device initiated resume race with roothub autosuspend
Date: Wed, 08 Jan 2020 19:43:51 +0000	[thread overview]
Message-ID: <lsq.1578512578.115859111@decadent.org.uk> (raw)
In-Reply-To: <lsq.1578512578.117275639@decadent.org.uk>

3.16.81-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Mathias Nyman <mathias.nyman@linux.intel.com>

commit 057d476fff778f1d3b9f861fdb5437ea1a3cfc99 upstream.

A race in xhci USB3 remote wake handling may force device back to suspend
after it initiated resume siganaling, causing a missed resume event or warm
reset of device.

When a USB3 link completes resume signaling and goes to enabled (UO)
state a interrupt is issued and the interrupt handler will clear the
bus_state->port_remote_wakeup resume flag, allowing bus suspend.

If the USB3 roothub thread just finished reading port status before
the interrupt, finding ports still in suspended (U3) state, but hasn't
yet started suspending the hub, then the xhci interrupt handler will clear
the flag that prevented roothub suspend and allow bus to suspend, forcing
all port links back to suspended (U3) state.

Example case:
usb_runtime_suspend() # because all ports still show suspended U3
  usb_suspend_both()
    hub_suspend();   # successful as hub->wakeup_bits not set yet
==> INTERRUPT
xhci_irq()
  handle_port_status()
    clear bus_state->port_remote_wakeup
    usb_wakeup_notification()
      sets hub->wakeup_bits;
        kick_hub_wq()
<== END INTERRUPT
      hcd_bus_suspend()
        xhci_bus_suspend() # success as port_remote_wakeup bits cleared

Fix this by increasing roothub usage count during port resume to prevent
roothub autosuspend, and by making sure bus_state->port_remote_wakeup
flag is only cleared after resume completion is visible, i.e.
after xhci roothub returned U0 or other non-U3 link state link on a
get port status request.

Issue rootcaused by Chiasheng Lee

Cc: Lee, Hou-hsun <hou-hsun.lee@intel.com>
Reported-by: Lee, Chiasheng <chiasheng.lee@intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20191211142007.8847-3-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[Mathias Nyman: Backport for 4.9 and 4.4 stable kernels]
[bwh: Backported to 3.16: USB 3.0 SS is the highest speed we handle]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 drivers/usb/host/xhci-hub.c  | 8 ++++++++
 drivers/usb/host/xhci-ring.c | 6 +-----
 drivers/usb/host/xhci.h      | 1 +
 3 files changed, 10 insertions(+), 5 deletions(-)

--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -612,6 +612,14 @@ static u32 xhci_get_port_status(struct u
 			status |= USB_PORT_STAT_C_BH_RESET << 16;
 		if ((raw_port_status & PORT_CEC))
 			status |= USB_PORT_STAT_C_CONFIG_ERROR << 16;
+
+		/* USB3 remote wake resume signaling completed */
+		if (bus_state->port_remote_wakeup & (1 << wIndex) &&
+		    (raw_port_status & PORT_PLS_MASK) != XDEV_RESUME &&
+		    (raw_port_status & PORT_PLS_MASK) != XDEV_RECOVERY) {
+			bus_state->port_remote_wakeup &= ~(1 << wIndex);
+			usb_hcd_end_port_resume(&hcd->self, wIndex);
+		}
 	}
 
 	if (hcd->speed != HCD_USB3) {
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1605,9 +1605,6 @@ static void handle_port_status(struct xh
 		usb_hcd_resume_root_hub(hcd);
 	}
 
-	if (hcd->speed == HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE)
-		bus_state->port_remote_wakeup &= ~(1 << faked_port_index);
-
 	if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) {
 		xhci_dbg(xhci, "port resume event for port %d\n", port_id);
 
@@ -1626,6 +1623,7 @@ static void handle_port_status(struct xh
 			bus_state->port_remote_wakeup |= 1 << faked_port_index;
 			xhci_test_and_clear_bit(xhci, port_array,
 					faked_port_index, PORT_PLC);
+			usb_hcd_start_port_resume(&hcd->self, faked_port_index);
 			xhci_set_link_state(xhci, port_array, faked_port_index,
 						XDEV_U0);
 			/* Need to wait until the next link state change
@@ -1663,8 +1661,6 @@ static void handle_port_status(struct xh
 		if (slot_id && xhci->devs[slot_id])
 			xhci_ring_device(xhci, slot_id);
 		if (bus_state->port_remote_wakeup & (1 << faked_port_index)) {
-			bus_state->port_remote_wakeup &=
-				~(1 << faked_port_index);
 			xhci_test_and_clear_bit(xhci, port_array,
 					faked_port_index, PORT_PLC);
 			usb_wakeup_notification(hcd->self.root_hub,
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -288,6 +288,7 @@ struct xhci_op_regs {
 #define XDEV_U3		(0x3 << 5)
 #define XDEV_INACTIVE	(0x6 << 5)
 #define XDEV_POLLING	(0x7 << 5)
+#define XDEV_RECOVERY	(0x8 << 5)
 #define XDEV_COMP_MODE  (0xa << 5)
 #define XDEV_RESUME	(0xf << 5)
 /* true: port has power (see HCC_PPC) */


  parent reply	other threads:[~2020-01-08 19:46 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-08 19:42 [PATCH 3.16 00/63] 3.16.81-rc1 review Ben Hutchings
2020-01-08 19:42 ` [PATCH 3.16 01/63] net: qlogic: Fix memory leak in ql_alloc_large_buffers Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 02/63] net: qlogic: Fix error paths in ql_alloc_large_buffers() Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 03/63] HID: sony: Update device ids Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 04/63] HID: sony: Support DS4 dongle Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 05/63] crypto: cts - fix crash on short inputs Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 06/63] tracing/uprobes: Fix output for multiple string arguments Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 07/63] libceph: handle an empty authorize reply Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 08/63] ALSA: compress: add support for 32bit calls in a 64bit kernel Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 09/63] mmc: debugfs: Add a restriction to mmc debugfs clock setting Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 10/63] mmc: sanitize 'bus width' in debug output Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 11/63] mmc: core: shut up "voltage-ranges unspecified" pr_info() Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 12/63] usb: dwc3: gadget: Fix suspend/resume during device mode Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 13/63] arm64: mm: Add trace_irqflags annotations to do_debug_exception() Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 14/63] mmc: core: fix using wrong io voltage if mmc_select_hs200 fails Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 15/63] mm/rmap: replace BUG_ON(anon_vma->degree) with VM_WARN_ON Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 16/63] kbuild: setlocalversion: print error to STDERR Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 17/63] usb: gadget: composite: fix dereference after null check coverify warning Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 18/63] usb: gadget: serial: fix re-ordering of tx data Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 19/63] usb: gadget: Add the gserial port checking in gs_start_tx() Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 20/63] tcp/dccp: drop SYN packets if accept queue is full Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 21/63] arm64: traps: disable irq in die() Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 22/63] usb: renesas_usbhs: gadget: fix unused-but-set-variable warning Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 23/63] xhci: Fix port resume done detection for SS ports with LPM enabled Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 24/63] mmc: block: Allow more than 8 partitions per card Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 25/63] arm64: fix COMPAT_SHMLBA definition for large pages Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 26/63] ARM: 8458/1: bL_switcher: add GIC dependency Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 27/63] net: diag: support v4mapped sockets in inet_diag_find_one_icsk() Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 28/63] asm-generic: Fix local variable shadow in __set_fixmap_offset Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 29/63] staging: ashmem: Avoid deadlock with mmap/shrink Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 30/63] staging: ashmem: Add missing include Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 31/63] staging: ion: Set minimum carveout heap allocation order to PAGE_SHIFT Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 32/63] staging: goldfish: audio: fix compiliation on arm Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 33/63] ARM: 8510/1: rework ARM_CPU_SUSPEND dependencies Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 34/63] arm64/kernel: fix incorrect EL0 check in inv_entry macro Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 35/63] arm64: kernel: Include _AC definition in page.h Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 36/63] suspend: simplify block I/O handling Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 37/63] PM / Hibernate: Call flush_icache_range() on pages restored in-place Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 38/63] usb: gadget: configfs: add mutex lock before unregister gadget Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 39/63] usb: gadget: rndis: free response queue during REMOTE_NDIS_RESET_MSG Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 40/63] video: fbdev: Set pixclock = 0 in goldfishfb Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 41/63] arm64: kconfig: drop CONFIG_RTC_LIB dependency Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 42/63] mmc: mmc: fix switch timeout issue caused by jiffies precision Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 43/63] cfg80211: size various nl80211 messages correctly Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 44/63] arm64: support keyctl() system call in 32-bit mode Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 45/63] stmmac: copy unicast mac address to MAC registers Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 46/63] arm64: debug: Don't propagate UNKNOWN FAR into si_code for debug signals Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 47/63] arm64: debug: Ensure debug handlers check triggering exception level Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 48/63] x86/atomic: Fix smp_mb__{before,after}_atomic() Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 49/63] locking,x86: Kill atomic_or_long() Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 50/63] locking/x86: Remove the unused atomic_inc_short() methd Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 51/63] dmaengine: qcom: bam_dma: Fix resource leak Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 52/63] mwifiex: Fix NL80211_TX_POWER_LIMITED Ben Hutchings
2020-01-08 19:43 ` Ben Hutchings [this message]
2020-01-08 19:43 ` [PATCH 3.16 54/63] Make filldir[64]() verify the directory entry filename is valid Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 55/63] filldir[64]: remove WARN_ON_ONCE() for bad directory entries Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 56/63] ext4: Introduce ext4_clamp_want_extra_isize() Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 57/63] ext4: add more paranoia checking in ext4_expand_extra_isize handling Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 58/63] Revert "sched/fair: Fix bandwidth timer clock drift condition" Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 59/63] can: kvaser_usb: kvaser_usb_leaf: Fix some info-leaks to USB devices Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 60/63] media: cpia2: Fix use-after-free in cpia2_exit Ben Hutchings
2020-01-08 19:43 ` [PATCH 3.16 61/63] mwifiex: don't follow AP if country code received from EEPROM Ben Hutchings
2020-01-08 19:44 ` [PATCH 3.16 62/63] mwifiex: fix possible heap overflow in mwifiex_process_country_ie() Ben Hutchings
2020-01-09 12:12   ` Salvatore Bonaccorso
2020-01-10 16:01     ` Ben Hutchings
2020-01-08 19:44 ` [PATCH 3.16 63/63] scsi: libsas: stop discovering if oob mode is disconnected Ben Hutchings
2020-01-08 22:52 ` [PATCH 3.16 00/63] 3.16.81-rc1 review Guenter Roeck
2020-01-09  1:14   ` Ben Hutchings

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=lsq.1578512578.115859111@decadent.org.uk \
    --to=ben@decadent.org.uk \
    --cc=akpm@linux-foundation.org \
    --cc=chiasheng.lee@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hou-hsun.lee@intel.com \
    --cc=kda@linux-powerpc.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathias.nyman@linux.intel.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.