blob: 02d55b5c7e766393212ec52057900aedc326804c [file] [log] [blame]
From f209a74adc0dd4319e563dfd7e4a6cd3cae8b161 Mon Sep 17 00:00:00 2001
From: Lu Baolu <baolu.lu@linux.intel.com>
Date: Thu, 5 Oct 2017 11:21:42 +0300
Subject: [PATCH 0249/1795] usb: xhci: Fix memory leak when xhci_disable_slot()
returns error
If xhci_disable_slot() returns success, a disable slot command
trb was queued in the command ring. The command completion
handler will free the virtual device data structure associated
with the slot. On the other hand, when xhci_disable_slot()
returns error, the invokers should take the responsibilities to
free the slot related data structure. Otherwise, memory leakage
happens.
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 11ec7588a10d4bc2e1e385ac565d2166d375fba1)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Conflicts:
drivers/usb/host/xhci.c
---
drivers/usb/host/xhci.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 920bfb8162f7..6dc536fa2e3b 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3606,11 +3606,9 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
}
virt_dev->udev = NULL;
- xhci_disable_slot(xhci, udev->slot_id);
- /*
- * Event command completion handler will free any data structures
- * associated with the slot. XXX Can free sleep?
- */
+ ret = xhci_disable_slot(xhci, udev->slot_id);
+ if (ret)
+ xhci_free_virt_device(xhci, udev->slot_id);
}
int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
@@ -3757,7 +3755,11 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
return 1;
disable_slot:
- return xhci_disable_slot(xhci, udev->slot_id);
+ ret = xhci_disable_slot(xhci, udev->slot_id);
+ if (ret)
+ xhci_free_virt_device(xhci, udev->slot_id);
+
+ return 0;
}
/*
--
2.19.0