From patchwork Thu Aug 25 15:08:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 12954990 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B220C32774 for ; Thu, 25 Aug 2022 15:07:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238853AbiHYPHg (ORCPT ); Thu, 25 Aug 2022 11:07:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237360AbiHYPHe (ORCPT ); Thu, 25 Aug 2022 11:07:34 -0400 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 17AF780B41 for ; Thu, 25 Aug 2022 08:07:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1661440054; x=1692976054; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=98pTz264WIAILIYNx8GIZGA3HQbV043MLCs4XkgjBZ8=; b=gIQylwi9mwD/s50T6ui82EYYggg49d2PbocgPt1lmQ1o8veEQHfq7TZT PEs2Ku7egwlluWSr9uwSbZIS9xDJbYsgxniWHlwM1jfgc3APH5k65RDpA SIi09yMuOZdZkxeyOZ9mkiw0BtzSiXqAAs7NbipTdPME6aPn8LaEcGDz/ THc7KT31AYp5wOx4OxknUOh9UJp60GSKOvL8IRxKUpEOu2veDqhfHnznh dulsE9aCBpgU6lGqTbVpCFycJiq3M34Va72PproZGbp08xxqWCfT0Nw4z Y72JlcjlUyeIB4R+bP4ujlPsC5c9zLcCQ1xLVOZGJf8lnmcYyFGsCliTL Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10450"; a="355981794" X-IronPort-AV: E=Sophos;i="5.93,263,1654585200"; d="scan'208";a="355981794" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Aug 2022 08:07:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,263,1654585200"; d="scan'208";a="643284822" Received: from mattu-haswell.fi.intel.com ([10.237.72.199]) by orsmga001.jf.intel.com with ESMTP; 25 Aug 2022 08:07:29 -0700 From: Mathias Nyman To: Cc: , Mathias Nyman , Alexey Sheplyakov Subject: [PATCH 1/3] xhci: Fix null pointer dereference in remove if xHC has only one roothub Date: Thu, 25 Aug 2022 18:08:38 +0300 Message-Id: <20220825150840.132216-2-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220825150840.132216-1-mathias.nyman@linux.intel.com> References: <20220825150840.132216-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The remove path in xhci platform driver tries to remove and put both main and shared hcds even if only a main hcd exists (one roothub) This causes a null pointer dereference in reboot for those controllers. Check that the shared_hcd exists before trying to remove it. Fixes: e0fe986972f5 ("usb: host: xhci-plat: prepare operation w/o shared hcd") Reported-by: Alexey Sheplyakov Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-plat.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 044855818cb1..a8641b6536ee 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -398,12 +398,17 @@ static int xhci_plat_remove(struct platform_device *dev) pm_runtime_get_sync(&dev->dev); xhci->xhc_state |= XHCI_STATE_REMOVING; - usb_remove_hcd(shared_hcd); - xhci->shared_hcd = NULL; + if (shared_hcd) { + usb_remove_hcd(shared_hcd); + xhci->shared_hcd = NULL; + } + usb_phy_shutdown(hcd->usb_phy); usb_remove_hcd(hcd); - usb_put_hcd(shared_hcd); + + if (shared_hcd) + usb_put_hcd(shared_hcd); clk_disable_unprepare(clk); clk_disable_unprepare(reg_clk); From patchwork Thu Aug 25 15:08:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 12954992 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01134C28D13 for ; Thu, 25 Aug 2022 15:07:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240249AbiHYPHg (ORCPT ); Thu, 25 Aug 2022 11:07:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35550 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237455AbiHYPHf (ORCPT ); Thu, 25 Aug 2022 11:07:35 -0400 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 969A981B2E; Thu, 25 Aug 2022 08:07:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1661440054; x=1692976054; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1DOhxGeiZXBrAneenWdEy15uEJy6cOb8JqHxpZ9EpwA=; b=PzLu4/fdoCIkGhByX1eE4hWzpCsYAtRdIcwUtpd2kRRxPEvdnekDQ6SF RooW6HNRktrEcZwA9SP4tYw0U9zJubUM1Cohoi1kcPLr73VHyJQv+u4vX SBhPhKbxVn2KCZao/7DUFWpi4LM4+NMvAMevtgnK3Ug4W3jgUFK3XXFxu IH9uDcM8hQ3KU90nIonexBSSOzMj8jVEf8AjzT6ShJHyJ5nLM+plASnyz dLMtcsFvQNfj9uFQaUpBqG8dk4AMVfF3pgX8Fn9596GE3A2Ds8Oku3zJt dggqJmNFbFGvMQmQN0IRIZ9NSRnLat7AldfW0TBXEm0J3kJup6bZw7Lhf A==; X-IronPort-AV: E=McAfee;i="6500,9779,10450"; a="355981801" X-IronPort-AV: E=Sophos;i="5.93,263,1654585200"; d="scan'208";a="355981801" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Aug 2022 08:07:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,263,1654585200"; d="scan'208";a="643284826" Received: from mattu-haswell.fi.intel.com ([10.237.72.199]) by orsmga001.jf.intel.com with ESMTP; 25 Aug 2022 08:07:31 -0700 From: Mathias Nyman To: Cc: , Mathias Nyman , stable@vger.kernel.org Subject: [PATCH 2/3] xhci: Add grace period after xHC start to prevent premature runtime suspend. Date: Thu, 25 Aug 2022 18:08:39 +0300 Message-Id: <20220825150840.132216-3-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220825150840.132216-1-mathias.nyman@linux.intel.com> References: <20220825150840.132216-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org After xHC controller is started, either in probe or resume, it can take a while before any of the connected usb devices are visible to the roothub due to link training. It's possible xhci driver loads, sees no acivity and suspends the host before the USB device is visible. In one testcase with a hotplugged xHC controller the host finally detected the connected USB device and generated a wake 500ms after host initial start. If hosts didn't suspend the device duringe training it probablty wouldn't take up to 500ms to detect it, but looking at specs reveal USB3 link training has a couple long timeout values, such as 120ms RxDetectQuietTimeout, and 360ms PollingLFPSTimeout. So Add a 500ms grace period that keeps polling the roothub for 500ms after start, preventing runtime suspend until USB devices are detected. Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-hub.c | 11 +++++++++++ drivers/usb/host/xhci.c | 4 +++- drivers/usb/host/xhci.h | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 0fdc014c9401..b30298986a69 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1648,6 +1648,17 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) status = bus_state->resuming_ports; + /* + * SS devices are only visible to roothub after link training completes. + * Keep polling roothubs for a grace period after xHC start + */ + if (xhci->run_graceperiod) { + if (time_before(jiffies, xhci->run_graceperiod)) + status = 1; + else + xhci->run_graceperiod = 0; + } + mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC; /* For each port, did anything change? If so, set that bit in buf. */ diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 65858f607437..1afd32beec99 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -151,9 +151,11 @@ int xhci_start(struct xhci_hcd *xhci) xhci_err(xhci, "Host took too long to start, " "waited %u microseconds.\n", XHCI_MAX_HALT_USEC); - if (!ret) + if (!ret) { /* clear state flags. Including dying, halted or removing */ xhci->xhc_state = 0; + xhci->run_graceperiod = jiffies + msecs_to_jiffies(500); + } return ret; } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 1960b47acfb2..df6f2ebaff18 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1826,7 +1826,7 @@ struct xhci_hcd { /* Host controller watchdog timer structures */ unsigned int xhc_state; - + unsigned long run_graceperiod; u32 command; struct s3_save s3; /* Host controller is dying - not responding to commands. "I'm not dead yet!" From patchwork Thu Aug 25 15:08:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 12954991 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7D50C64990 for ; Thu, 25 Aug 2022 15:07:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240377AbiHYPHh (ORCPT ); Thu, 25 Aug 2022 11:07:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35562 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238665AbiHYPHg (ORCPT ); Thu, 25 Aug 2022 11:07:36 -0400 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE12D857FD for ; Thu, 25 Aug 2022 08:07:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1661440055; x=1692976055; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cte672H7taZH7elV8fvIQi/gWfBYhev7owAtmdxxIbM=; b=WWmacEah6UnFQEZEMc9NCZmRGjs6dp56Hg6vw710YIz0HtzPyqFgVaQ7 fv92mTYWA6GHXaDev/M988yncf4ws0elA6d/5UR+0WVkc/TvNGuOU3ZRi VLeds1L12ZjWKGaRBl7uAOs146CMWwAZBHcbhbmwpfDRf2mpvq+VkWomp IKpX7rxpq2W2QuBqnIB1oa0gK/HJH7SIA8vG7p4AiNJrhuJxl3YMunKNu mr51DQCeBtkL7jV1ec6/WIRvhcN+kpmPjhx7YnwHrGzFg2JVVaSwrrpH1 H9NnoBWt82Hmc21jhrsE6F0+rh/2TcmduLLX3qoVi2YKhPcqChPzIuUH9 A==; X-IronPort-AV: E=McAfee;i="6500,9779,10450"; a="355981806" X-IronPort-AV: E=Sophos;i="5.93,263,1654585200"; d="scan'208";a="355981806" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Aug 2022 08:07:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,263,1654585200"; d="scan'208";a="643284840" Received: from mattu-haswell.fi.intel.com ([10.237.72.199]) by orsmga001.jf.intel.com with ESMTP; 25 Aug 2022 08:07:33 -0700 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 3/3] Revert "xhci: turn off port power in shutdown" Date: Thu, 25 Aug 2022 18:08:40 +0300 Message-Id: <20220825150840.132216-4-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220825150840.132216-1-mathias.nyman@linux.intel.com> References: <20220825150840.132216-1-mathias.nyman@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org This reverts commit 83810f84ecf11dfc5a9414a8b762c3501b328185. Turning off port power in shutdown did cause issues such as a laptop not proprly powering off, and some specific usb devies failing to enumerate the subsequent boot after a warm reset. So revert this. Fixes: 83810f84ecf1 ("xhci: turn off port power in shutdown") Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-hub.c | 2 +- drivers/usb/host/xhci.c | 15 ++------------- drivers/usb/host/xhci.h | 2 -- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index b30298986a69..4619d5e89d5b 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -652,7 +652,7 @@ struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd) * It will release and re-aquire the lock while calling ACPI * method. */ -void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, +static void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, u16 index, bool on, unsigned long *flags) __must_hold(&xhci->lock) { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1afd32beec99..38649284ff88 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -793,8 +793,6 @@ static void xhci_stop(struct usb_hcd *hcd) void xhci_shutdown(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); - unsigned long flags; - int i; if (xhci->quirks & XHCI_SPURIOUS_REBOOT) usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev)); @@ -810,21 +808,12 @@ void xhci_shutdown(struct usb_hcd *hcd) del_timer_sync(&xhci->shared_hcd->rh_timer); } - spin_lock_irqsave(&xhci->lock, flags); + spin_lock_irq(&xhci->lock); xhci_halt(xhci); - - /* Power off USB2 ports*/ - for (i = 0; i < xhci->usb2_rhub.num_ports; i++) - xhci_set_port_power(xhci, xhci->main_hcd, i, false, &flags); - - /* Power off USB3 ports*/ - for (i = 0; i < xhci->usb3_rhub.num_ports; i++) - xhci_set_port_power(xhci, xhci->shared_hcd, i, false, &flags); - /* Workaround for spurious wakeups at shutdown with HSW */ if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) xhci_reset(xhci, XHCI_RESET_SHORT_USEC); - spin_unlock_irqrestore(&xhci->lock, flags); + spin_unlock_irq(&xhci->lock); xhci_cleanup_msix(xhci); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index df6f2ebaff18..7caa0db5e826 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -2196,8 +2196,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1); struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd); -void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, u16 index, - bool on, unsigned long *flags); void xhci_hc_died(struct xhci_hcd *xhci);