FAILED: patch "[PATCH] xhci: Fix leaking USB3 shared_hcd at xhci removal" failed to apply to 4.14-stable tree
Subsystems (6)
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
f068090426ea8d72c408ebd42953a82a88e2282cMon Sep 17 00:00:00 2001
From: Mathias Nyman <[email protected]>
Date: Fri, 9 Nov 2018 17:21:17 +0200
Subject: [PATCH] xhci: Fix leaking USB3 shared_hcd at xhci removal
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")
drivers/usb/host/xhci-histb.c +4 -2
@@ -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);
drivers/usb/host/xhci-mtk.c +4 -2
@@ -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);
drivers/usb/host/xhci-pci.c +1 -0
@@ -380,6 +380,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 */
drivers/usb/host/xhci-plat.c +4 -2
@@ -362,14 +362,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);
drivers/usb/host/xhci-tegra.c +1 -0
@@ -1303,6 +1303,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);
drivers/usb/host/xhci.c +0 -2
@@ -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 ; }
Hi Greg,
Quoted 5 lines · On Wed, Nov 28, 2018 at 10:26:44AM +0100, [email protected] wrote:
The patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
The attached backported patch should apply to 4.14-stable tree. The original patch was also changing drivers/usb/host/xhci-histb.c which is not needed in v4.14.y as that file was created in v4.18 by:c508f41da078 ("xhci: hisilicon: support HiSilicon STB xHCI host controller")
--
Regards
Sudip
From 103fd0c5188d19284967e1019588700e2b2a6a67 Mon Sep 17 00:00:00 2001
From: Mathias Nyman <[email protected]>
Date: Fri, 9 Nov 2018 17:21:17 +0200
Subject: [PATCH] xhci: Fix leaking USB3 shared_hcd at xhci removal
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")
--- 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 -- 5 files changed, 10 insertions(+), 6 deletions(-)
drivers/usb/host/xhci-mtk.c +4 -2
@@ -724,14 +724,16 @@ 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 ;xhci_mtk_phy_power_off (mtk);xhci_mtk_phy_exit (mtk);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);
drivers/usb/host/xhci-pci.c +1 -0
@@ -370,6 +370,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 */
drivers/usb/host/xhci-plat.c +4 -2
@@ -332,14 +332,16 @@ static int xhci_plat_remove(struct platform_device *dev)struct usb_hcd *hcd =platform_get_drvdata (dev);struct xhci_hcd *xhci =hcd_to_xhci (hcd);struct clk *clk = xhci->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);if (!IS_ERR (clk))clk_disable_unprepare (clk);
drivers/usb/host/xhci-tegra.c +1 -0
@@ -1178,6 +1178,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);
drivers/usb/host/xhci.c +0 -2
@@ -669,8 +669,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 ; }
Signature · 1 line
2.11.0
Greg KH
maintainerQuoted 9 lines · Sudip Mukherjee
Hi Greg,
Quoted 5 lines · On Wed, Nov 28, 2018 at 10:26:44AM +0100, [email protected] wrote:
The patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Quoted 4 lines
The attached backported patch should apply to 4.14-stable tree. The original patch was also changing
drivers/usb/host/xhci-histb.cwhich is not needed in v4.14.y as that file was created in v4.18 by:c508f41da078("xhci: hisilicon: support HiSilicon STB xHCI host controller")
Now queued up, thanks,
greg k-h