Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2545891imu; Thu, 29 Nov 2018 06:41:37 -0800 (PST) X-Google-Smtp-Source: AFSGD/XKwALatT+3kvu2bWWcc2/p06fHYDlFoWzU0J+qpqtsgdG2o8IC/gGI57SU3IfiB3K6TnHt X-Received: by 2002:a62:5bc7:: with SMTP id p190-v6mr1619278pfb.175.1543502497412; Thu, 29 Nov 2018 06:41:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543502497; cv=none; d=google.com; s=arc-20160816; b=qihziXxcci7QGK4volFtdwtdBNNIq4ATdSGF8AuKekKj+jgCIZXYbhluRWkACpHwCc n65V5HG7NvAvZ/BzF4/1qCPqpN2vskrxqr56RKB8BZoo905sx68nSGugL4MAoGCc5/9L vbnjxq0WMIMGmUFKZyYlWSaiD2ku2yXECWT7lcLgXErmmniih113up1W5tuk9b+11Ao5 VExc2yID76vOZuchWcuc/7i3+R0s143DTZ6EzJrDf2awI52wE0yDbEwsNQgvY9ehY3zE Y89Pgjy+I/oR1eDpzsAVzteUL1atVGF76aOud4GUF5q3jZu7bZtyp6O8Y40d4LxSCKcp JUmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=fJKgNOEdHqBuX5fSOvBiS0nn2xrpvIy5oCCosnKp7S0=; b=IZwaPQ7UxN/QKz0D2GcU+xv6ww2Ss0s4AvQ5M2p6HHtPrUAufaWngWHCtlY4h98HeC T0dZplZd+4qLxGEzARGrSKbT4QfgFhmxySSbqeL/1MZi03doesH7otBJYbvH6+i7sc8H QVD1gNn9LDewEGdxcW4Hxdt/Ocgvc74qoRbkvbAGif/a47XV0V1do04/qomw3BGfPp6L HU0ErMSb6QjaScBNKlmc1hNKa3crAJb2AqtS+DQv29cE/5CMi6mjcWBtN3M+skbLS+ms guwoxjRfowAoQoKPEg6zlwP2xsNWZoEbNUkB/fwF6+mS/wxCRGcuSIwjXTEHVRvj5GEH +DcQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=wEQ4I4lQ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b124si2293062pfg.47.2018.11.29.06.41.13; Thu, 29 Nov 2018 06:41:37 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=wEQ4I4lQ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388300AbeK3Beg (ORCPT + 99 others); Thu, 29 Nov 2018 20:34:36 -0500 Received: from mail.kernel.org ([198.145.29.99]:35900 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731995AbeK3Beg (ORCPT ); Thu, 29 Nov 2018 20:34:36 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E211D2146F; Thu, 29 Nov 2018 14:29:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543501743; bh=/AmGkwG5XlI6MXB3ymuR/AtaJIVJa9HBcjeVfh+3y8Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wEQ4I4lQoGxB3EUxevcPNrEuETOF/MsdIkTkOvGqP9TCWHH1F6HMMyqzkkABaqkja jnrOf1Gw0wgV5baFNNTAOPZzEk4tOztbfq2S6a8FDZsaKWNhXogXWpPsdQJQooy/O2 0OUB/hnXJ5HesO+BrfLBkJU8Fo2NpuXOppqDxVzk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Joel Stanley , Chunfeng Yun , Thierry Reding , Jianguo Sun , Jack Pham , Peter Chen , Mathias Nyman Subject: [PATCH 4.19 008/110] xhci: Fix leaking USB3 shared_hcd at xhci removal Date: Thu, 29 Nov 2018 15:11:39 +0100 Message-Id: <20181129135921.578477412@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181129135921.231283053@linuxfoundation.org> References: <20181129135921.231283053@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Mathias Nyman commit f068090426ea8d72c408ebd42953a82a88e2282c upstream. Ensure that the shared_hcd pointer is valid when calling usb_put_hcd() The shared_hcd is removed and freed in xhci by first calling usb_remove_hcd(xhci->shared_hcd), and later usb_put_hcd(xhci->shared_hcd) Afer commit fe190ed0d602 ("xhci: Do not halt the host until both HCD have disconnected their devices.") the shared_hcd was never properly put as xhci->shared_hcd was set to NULL before usb_put_hcd(xhci->shared_hcd) was called. shared_hcd (USB3) is removed before primary hcd (USB2). While removing the primary hcd we might need to handle xhci interrupts to cleanly remove last USB2 devices, therefore we need to set xhci->shared_hcd to NULL before removing the primary hcd to let xhci interrupt handler know shared_hcd is no longer available. xhci-plat.c, xhci-histb.c and xhci-mtk first create both their hcd's before adding them. so to keep the correct reverse removal order use a temporary shared_hcd variable for them. For more details see commit 4ac53087d6d4 ("usb: xhci: plat: Create both HCDs before adding them") Fixes: fe190ed0d602 ("xhci: Do not halt the host until both HCD have disconnected their devices.") Cc: Joel Stanley Cc: Chunfeng Yun Cc: Thierry Reding Cc: Jianguo Sun Cc: Reported-by: Jack Pham Tested-by: Jack Pham Tested-by: Peter Chen Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-histb.c | 6 ++++-- drivers/usb/host/xhci-mtk.c | 6 ++++-- drivers/usb/host/xhci-pci.c | 1 + drivers/usb/host/xhci-plat.c | 6 ++++-- drivers/usb/host/xhci-tegra.c | 1 + drivers/usb/host/xhci.c | 2 -- 6 files changed, 14 insertions(+), 8 deletions(-) --- a/drivers/usb/host/xhci-histb.c +++ b/drivers/usb/host/xhci-histb.c @@ -325,14 +325,16 @@ static int xhci_histb_remove(struct plat struct xhci_hcd_histb *histb = platform_get_drvdata(dev); struct usb_hcd *hcd = histb->hcd; struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct usb_hcd *shared_hcd = xhci->shared_hcd; xhci->xhc_state |= XHCI_STATE_REMOVING; - usb_remove_hcd(xhci->shared_hcd); + usb_remove_hcd(shared_hcd); + xhci->shared_hcd = NULL; device_wakeup_disable(&dev->dev); usb_remove_hcd(hcd); - usb_put_hcd(xhci->shared_hcd); + usb_put_hcd(shared_hcd); xhci_histb_host_disable(histb); usb_put_hcd(hcd); --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -590,12 +590,14 @@ static int xhci_mtk_remove(struct platfo struct xhci_hcd_mtk *mtk = platform_get_drvdata(dev); struct usb_hcd *hcd = mtk->hcd; struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct usb_hcd *shared_hcd = xhci->shared_hcd; - usb_remove_hcd(xhci->shared_hcd); + usb_remove_hcd(shared_hcd); + xhci->shared_hcd = NULL; device_init_wakeup(&dev->dev, false); usb_remove_hcd(hcd); - usb_put_hcd(xhci->shared_hcd); + usb_put_hcd(shared_hcd); usb_put_hcd(hcd); xhci_mtk_sch_exit(mtk); xhci_mtk_clks_disable(mtk); --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -356,6 +356,7 @@ static void xhci_pci_remove(struct pci_d if (xhci->shared_hcd) { usb_remove_hcd(xhci->shared_hcd); usb_put_hcd(xhci->shared_hcd); + xhci->shared_hcd = NULL; } /* Workaround for spurious wakeups at shutdown with HSW */ --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -359,14 +359,16 @@ static int xhci_plat_remove(struct platf struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct clk *clk = xhci->clk; struct clk *reg_clk = xhci->reg_clk; + struct usb_hcd *shared_hcd = xhci->shared_hcd; xhci->xhc_state |= XHCI_STATE_REMOVING; - usb_remove_hcd(xhci->shared_hcd); + usb_remove_hcd(shared_hcd); + xhci->shared_hcd = NULL; usb_phy_shutdown(hcd->usb_phy); usb_remove_hcd(hcd); - usb_put_hcd(xhci->shared_hcd); + usb_put_hcd(shared_hcd); clk_disable_unprepare(clk); clk_disable_unprepare(reg_clk); --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -1240,6 +1240,7 @@ static int tegra_xusb_remove(struct plat usb_remove_hcd(xhci->shared_hcd); usb_put_hcd(xhci->shared_hcd); + xhci->shared_hcd = NULL; usb_remove_hcd(tegra->hcd); usb_put_hcd(tegra->hcd); --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -719,8 +719,6 @@ static void xhci_stop(struct usb_hcd *hc /* Only halt host and free memory after both hcds are removed */ if (!usb_hcd_is_primary_hcd(hcd)) { - /* usb core will free this hcd shortly, unset pointer */ - xhci->shared_hcd = NULL; mutex_unlock(&xhci->mutex); return; }