All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
To: Mathias Nyman <mathias.nyman@linux.intel.com>
Cc: <jackp@codeaurora.org>, <peter.chen@nxp.com>, <linux-imx@nxp.com>,
	<linux-usb@vger.kernel.org>, <jun.li@nxp.com>, <joel@jms.id.au>,
	<mrana@codeaurora.org>, Thierry Reding <treding@nvidia.com>,
	Jianguo Sun <sunjianguo1@huawei.com>, <stable@vger.kernel.org>
Subject: Re: [RFT PATCH 1/2] xhci: Fix leaking USB3 shared_hcd at xhci removal
Date: Fri, 28 Sep 2018 10:16:10 +0800	[thread overview]
Message-ID: <1538100970.32173.58.camel@mhfsdcap03> (raw)
In-Reply-To: <1538065587-22997-1-git-send-email-mathias.nyman@linux.intel.com>

On Thu, 2018-09-27 at 19:26 +0300, Mathias Nyman wrote:
> 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 <joel@jms.id.au>
> Cc: Chunfeng Yun <chunfeng.yun@mediatek.com>
> Cc: Thierry Reding <treding@nvidia.com>
> Cc: Jianguo Sun <sunjianguo1@huawei.com>
> Cc: <stable@vger.kernel.org>
> Reported-by: Jack Pham <jackp@codeaurora.org>
> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> ---
>  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(-)
> 
> diff --git a/drivers/usb/host/xhci-histb.c b/drivers/usb/host/xhci-histb.c
> index 27f0016..3c4abb5 100644
> --- a/drivers/usb/host/xhci-histb.c
> +++ b/drivers/usb/host/xhci-histb.c
> @@ -325,14 +325,16 @@ static int xhci_histb_remove(struct platform_device *dev)
>  	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);
> diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
> index 71d0d33..60987c7 100644
> --- a/drivers/usb/host/xhci-mtk.c
> +++ b/drivers/usb/host/xhci-mtk.c
> @@ -590,12 +590,14 @@ static int xhci_mtk_remove(struct platform_device *dev)
>  	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);
> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> index 51dd8e0..92fd6b6 100644
> --- 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_dev *dev)
>  	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 */
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 94e9392..e5da8ce 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -359,14 +359,16 @@ static int xhci_plat_remove(struct platform_device *dev)
>  	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);
> diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
> index 4b463e5..b1cce98 100644
> --- a/drivers/usb/host/xhci-tegra.c
> +++ b/drivers/usb/host/xhci-tegra.c
> @@ -1240,6 +1240,7 @@ static int tegra_xusb_remove(struct platform_device *pdev)
>  
>  	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);
>  
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 0420eef..c928dbb 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -719,8 +719,6 @@ static void xhci_stop(struct usb_hcd *hcd)
>  
>  	/* 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;
>  	}

Tested-by: Chunfeng Yun <chunfeng.yun@mediatek.com>

Thanks

WARNING: multiple messages have this Message-ID (diff)
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
To: Mathias Nyman <mathias.nyman@linux.intel.com>
Cc: jackp@codeaurora.org, peter.chen@nxp.com, linux-imx@nxp.com,
	linux-usb@vger.kernel.org, jun.li@nxp.com, joel@jms.id.au,
	mrana@codeaurora.org, Thierry Reding <treding@nvidia.com>,
	Jianguo Sun <sunjianguo1@huawei.com>,
	stable@vger.kernel.org
Subject: [RFT,1/2] xhci: Fix leaking USB3 shared_hcd at xhci removal
Date: Fri, 28 Sep 2018 10:16:10 +0800	[thread overview]
Message-ID: <1538100970.32173.58.camel@mhfsdcap03> (raw)

On Thu, 2018-09-27 at 19:26 +0300, Mathias Nyman wrote:
> 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 <joel@jms.id.au>
> Cc: Chunfeng Yun <chunfeng.yun@mediatek.com>
> Cc: Thierry Reding <treding@nvidia.com>
> Cc: Jianguo Sun <sunjianguo1@huawei.com>
> Cc: <stable@vger.kernel.org>
> Reported-by: Jack Pham <jackp@codeaurora.org>
> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> ---
>  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(-)
> 
> diff --git a/drivers/usb/host/xhci-histb.c b/drivers/usb/host/xhci-histb.c
> index 27f0016..3c4abb5 100644
> --- a/drivers/usb/host/xhci-histb.c
> +++ b/drivers/usb/host/xhci-histb.c
> @@ -325,14 +325,16 @@ static int xhci_histb_remove(struct platform_device *dev)
>  	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);
> diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
> index 71d0d33..60987c7 100644
> --- a/drivers/usb/host/xhci-mtk.c
> +++ b/drivers/usb/host/xhci-mtk.c
> @@ -590,12 +590,14 @@ static int xhci_mtk_remove(struct platform_device *dev)
>  	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);
> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> index 51dd8e0..92fd6b6 100644
> --- 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_dev *dev)
>  	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 */
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 94e9392..e5da8ce 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -359,14 +359,16 @@ static int xhci_plat_remove(struct platform_device *dev)
>  	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);
> diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
> index 4b463e5..b1cce98 100644
> --- a/drivers/usb/host/xhci-tegra.c
> +++ b/drivers/usb/host/xhci-tegra.c
> @@ -1240,6 +1240,7 @@ static int tegra_xusb_remove(struct platform_device *pdev)
>  
>  	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);
>  
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 0420eef..c928dbb 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -719,8 +719,6 @@ static void xhci_stop(struct usb_hcd *hcd)
>  
>  	/* 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;
>  	}

Tested-by: Chunfeng Yun <chunfeng.yun@mediatek.com>

Thanks

  parent reply	other threads:[~2018-09-28  8:38 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-27  1:39 [1/3] usb: host: xhci: fix oops when removing hcd Jack Pham
2018-09-27 16:26 ` [RFT PATCH 1/2] xhci: Fix leaking USB3 shared_hcd at xhci removal Mathias Nyman
2018-09-27 16:26   ` [RFT,1/2] " Mathias Nyman
2018-09-27 16:26   ` [RFT PATCH 2/2] xhci: handle port status events for removed USB3 hcd Mathias Nyman
2018-09-27 16:26     ` [RFT,2/2] " Mathias Nyman
2018-09-27 16:34     ` [RFT PATCH 2/2] " Mathias Nyman
2018-09-27 16:34       ` [RFT,2/2] " Mathias Nyman
2018-09-28  3:35       ` [RFT PATCH 2/2] " Peter Chen
2018-09-28  3:35         ` [RFT,2/2] " Peter Chen
2018-09-28 18:10         ` [RFT PATCH 2/2] " Jack Pham
2018-09-28 18:10           ` [RFT,2/2] " Jack Pham
2018-10-01 15:52           ` [RFT PATCH 2/2] " Mathias Nyman
2018-10-01 15:52             ` [RFT,2/2] " Mathias Nyman
2018-09-28  2:16   ` Chunfeng Yun [this message]
2018-09-28  2:16     ` [RFT,1/2] xhci: Fix leaking USB3 shared_hcd at xhci removal Chunfeng Yun
2018-09-28  3:35   ` [RFT PATCH 1/2] " Peter Chen
2018-09-28  3:35     ` [RFT,1/2] " Peter Chen
2018-09-28 18:12   ` [RFT PATCH 1/2] " Jack Pham
2018-09-28 18:12     ` [RFT,1/2] " Jack Pham

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=1538100970.32173.58.camel@mhfsdcap03 \
    --to=chunfeng.yun@mediatek.com \
    --cc=jackp@codeaurora.org \
    --cc=joel@jms.id.au \
    --cc=jun.li@nxp.com \
    --cc=linux-imx@nxp.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@linux.intel.com \
    --cc=mrana@codeaurora.org \
    --cc=peter.chen@nxp.com \
    --cc=stable@vger.kernel.org \
    --cc=sunjianguo1@huawei.com \
    --cc=treding@nvidia.com \
    /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.