From a265205b25d8dc411fd33d45ba7fd0b6fdedbb9f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 26 Feb 2020 09:53:22 +0100 Subject: [PATCH] 5.5-stable patches added patches: xhci-apply-xhci_pme_stuck_quirk-to-intel-comet-lake-platforms.patch xhci-fix-memory-leak-when-caching-protocol-extended-capability-psi-tables-take-2.patch xhci-fix-runtime-pm-enabling-for-quirky-intel-hosts.patch xhci-force-maximum-packet-size-for-full-speed-bulk-devices-to-valid-range.patch --- queue-5.5/series | 4 + ..._quirk-to-intel-comet-lake-platforms.patch | 41 +++ ...xtended-capability-psi-tables-take-2.patch | 265 ++++++++++++++++++ ...e-pm-enabling-for-quirky-intel-hosts.patch | 55 ++++ ...ll-speed-bulk-devices-to-valid-range.patch | 51 ++++ 5 files changed, 416 insertions(+) create mode 100644 queue-5.5/xhci-apply-xhci_pme_stuck_quirk-to-intel-comet-lake-platforms.patch create mode 100644 queue-5.5/xhci-fix-memory-leak-when-caching-protocol-extended-capability-psi-tables-take-2.patch create mode 100644 queue-5.5/xhci-fix-runtime-pm-enabling-for-quirky-intel-hosts.patch create mode 100644 queue-5.5/xhci-force-maximum-packet-size-for-full-speed-bulk-devices-to-valid-range.patch diff --git a/queue-5.5/series b/queue-5.5/series index 5a365e07558..f7cc223f28e 100644 --- a/queue-5.5/series +++ b/queue-5.5/series @@ -28,3 +28,7 @@ vt-selection-close-sel_buffer-race.patch vt-vt_ioctl-fix-race-in-vt_resizex.patch staging-android-ashmem-disallow-ashmem-memory-from-being-remapped.patch staging-vt6656-fix-sign-of-rx_dbm-to-bb_pre_ed_rssi.patch +xhci-force-maximum-packet-size-for-full-speed-bulk-devices-to-valid-range.patch +xhci-fix-runtime-pm-enabling-for-quirky-intel-hosts.patch +xhci-apply-xhci_pme_stuck_quirk-to-intel-comet-lake-platforms.patch +xhci-fix-memory-leak-when-caching-protocol-extended-capability-psi-tables-take-2.patch diff --git a/queue-5.5/xhci-apply-xhci_pme_stuck_quirk-to-intel-comet-lake-platforms.patch b/queue-5.5/xhci-apply-xhci_pme_stuck_quirk-to-intel-comet-lake-platforms.patch new file mode 100644 index 00000000000..8ca086d2179 --- /dev/null +++ b/queue-5.5/xhci-apply-xhci_pme_stuck_quirk-to-intel-comet-lake-platforms.patch @@ -0,0 +1,41 @@ +From a3ae87dce3a5abe0b57c811bab02b2564b574106 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 10 Feb 2020 15:45:53 +0200 +Subject: xhci: apply XHCI_PME_STUCK_QUIRK to Intel Comet Lake platforms + +From: Mathias Nyman + +commit a3ae87dce3a5abe0b57c811bab02b2564b574106 upstream. + +Intel Comet Lake based platform require the XHCI_PME_STUCK_QUIRK +quirk as well. Without this xHC can not enter D3 in runtime suspend. + +Cc: stable@vger.kernel.org +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20200210134553.9144-5-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-pci.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -49,6 +49,7 @@ + #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_XHCI 0x15ec + #define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI 0x15f0 + #define PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI 0x8a13 ++#define PCI_DEVICE_ID_INTEL_CML_XHCI 0xa3af + + #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 + #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba +@@ -187,7 +188,8 @@ static void xhci_pci_quirks(struct devic + pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI || +- pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI)) { ++ pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI || ++ pdev->device == PCI_DEVICE_ID_INTEL_CML_XHCI)) { + xhci->quirks |= XHCI_PME_STUCK_QUIRK; + } + if (pdev->vendor == PCI_VENDOR_ID_INTEL && diff --git a/queue-5.5/xhci-fix-memory-leak-when-caching-protocol-extended-capability-psi-tables-take-2.patch b/queue-5.5/xhci-fix-memory-leak-when-caching-protocol-extended-capability-psi-tables-take-2.patch new file mode 100644 index 00000000000..5d5832d971f --- /dev/null +++ b/queue-5.5/xhci-fix-memory-leak-when-caching-protocol-extended-capability-psi-tables-take-2.patch @@ -0,0 +1,265 @@ +From cf0ee7c60c89641f6e4d1d3c7867fe32b9e30300 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Tue, 11 Feb 2020 17:01:58 +0200 +Subject: xhci: Fix memory leak when caching protocol extended capability PSI tables - take 2 + +From: Mathias Nyman + +commit cf0ee7c60c89641f6e4d1d3c7867fe32b9e30300 upstream. + +xhci driver assumed that xHC controllers have at most one custom +supported speed table (PSI) for all usb 3.x ports. +Memory was allocated for one PSI table under the xhci hub structure. + +Turns out this is not the case, some controllers have a separate +"supported protocol capability" entry with a PSI table for each port. +This means each usb3 roothub port can in theory support different custom +speeds. + +To solve this, cache all supported protocol capabilities with their PSI +tables in an array, and add pointers to the xhci port structure so that +every port points to its capability entry in the array. + +When creating the SuperSpeedPlus USB Device Capability BOS descriptor +for the xhci USB 3.1 roothub we for now will use only data from the +first USB 3.1 capable protocol capability entry in the array. +This could be improved later, this patch focuses resolving +the memory leak. + +Reported-by: Paul Menzel +Reported-by: Sajja Venkateswara Rao +Fixes: 47189098f8be ("xhci: parse xhci protocol speed ID list for usb 3.1 usage") +Cc: stable # v4.4+ +Signed-off-by: Mathias Nyman +Tested-by: Marek Szyprowski +Link: https://lore.kernel.org/r/20200211150158.14475-1-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hub.c | 25 ++++++++++++------ + drivers/usb/host/xhci-mem.c | 61 +++++++++++++++++++++++++++----------------- + drivers/usb/host/xhci.h | 14 +++++++--- + 3 files changed, 66 insertions(+), 34 deletions(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -55,6 +55,7 @@ static u8 usb_bos_descriptor [] = { + static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf, + u16 wLength) + { ++ struct xhci_port_cap *port_cap = NULL; + int i, ssa_count; + u32 temp; + u16 desc_size, ssp_cap_size, ssa_size = 0; +@@ -64,16 +65,24 @@ static int xhci_create_usb3_bos_desc(str + ssp_cap_size = sizeof(usb_bos_descriptor) - desc_size; + + /* does xhci support USB 3.1 Enhanced SuperSpeed */ +- if (xhci->usb3_rhub.min_rev >= 0x01) { ++ for (i = 0; i < xhci->num_port_caps; i++) { ++ if (xhci->port_caps[i].maj_rev == 0x03 && ++ xhci->port_caps[i].min_rev >= 0x01) { ++ usb3_1 = true; ++ port_cap = &xhci->port_caps[i]; ++ break; ++ } ++ } ++ ++ if (usb3_1) { + /* does xhci provide a PSI table for SSA speed attributes? */ +- if (xhci->usb3_rhub.psi_count) { ++ if (port_cap->psi_count) { + /* two SSA entries for each unique PSI ID, RX and TX */ +- ssa_count = xhci->usb3_rhub.psi_uid_count * 2; ++ ssa_count = port_cap->psi_uid_count * 2; + ssa_size = ssa_count * sizeof(u32); + ssp_cap_size -= 16; /* skip copying the default SSA */ + } + desc_size += ssp_cap_size; +- usb3_1 = true; + } + memcpy(buf, &usb_bos_descriptor, min(desc_size, wLength)); + +@@ -99,7 +108,7 @@ static int xhci_create_usb3_bos_desc(str + } + + /* If PSI table exists, add the custom speed attributes from it */ +- if (usb3_1 && xhci->usb3_rhub.psi_count) { ++ if (usb3_1 && port_cap->psi_count) { + u32 ssp_cap_base, bm_attrib, psi, psi_mant, psi_exp; + int offset; + +@@ -111,7 +120,7 @@ static int xhci_create_usb3_bos_desc(str + + /* attribute count SSAC bits 4:0 and ID count SSIC bits 8:5 */ + bm_attrib = (ssa_count - 1) & 0x1f; +- bm_attrib |= (xhci->usb3_rhub.psi_uid_count - 1) << 5; ++ bm_attrib |= (port_cap->psi_uid_count - 1) << 5; + put_unaligned_le32(bm_attrib, &buf[ssp_cap_base + 4]); + + if (wLength < desc_size + ssa_size) +@@ -124,8 +133,8 @@ static int xhci_create_usb3_bos_desc(str + * USB 3.1 requires two SSA entries (RX and TX) for every link + */ + offset = desc_size; +- for (i = 0; i < xhci->usb3_rhub.psi_count; i++) { +- psi = xhci->usb3_rhub.psi[i]; ++ for (i = 0; i < port_cap->psi_count; i++) { ++ psi = port_cap->psi[i]; + psi &= ~USB_SSP_SUBLINK_SPEED_RSVD; + psi_exp = XHCI_EXT_PORT_PSIE(psi); + psi_mant = XHCI_EXT_PORT_PSIM(psi); +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1915,17 +1915,17 @@ no_bw: + xhci->usb3_rhub.num_ports = 0; + xhci->num_active_eps = 0; + kfree(xhci->usb2_rhub.ports); +- kfree(xhci->usb2_rhub.psi); + kfree(xhci->usb3_rhub.ports); +- kfree(xhci->usb3_rhub.psi); + kfree(xhci->hw_ports); + kfree(xhci->rh_bw); + kfree(xhci->ext_caps); ++ for (i = 0; i < xhci->num_port_caps; i++) ++ kfree(xhci->port_caps[i].psi); ++ kfree(xhci->port_caps); ++ xhci->num_port_caps = 0; + + xhci->usb2_rhub.ports = NULL; +- xhci->usb2_rhub.psi = NULL; + xhci->usb3_rhub.ports = NULL; +- xhci->usb3_rhub.psi = NULL; + xhci->hw_ports = NULL; + xhci->rh_bw = NULL; + xhci->ext_caps = NULL; +@@ -2126,6 +2126,7 @@ static void xhci_add_in_port(struct xhci + u8 major_revision, minor_revision; + struct xhci_hub *rhub; + struct device *dev = xhci_to_hcd(xhci)->self.sysdev; ++ struct xhci_port_cap *port_cap; + + temp = readl(addr); + major_revision = XHCI_EXT_PORT_MAJOR(temp); +@@ -2160,31 +2161,39 @@ static void xhci_add_in_port(struct xhci + /* WTF? "Valid values are ‘1’ to MaxPorts" */ + return; + +- rhub->psi_count = XHCI_EXT_PORT_PSIC(temp); +- if (rhub->psi_count) { +- rhub->psi = kcalloc_node(rhub->psi_count, sizeof(*rhub->psi), +- GFP_KERNEL, dev_to_node(dev)); +- if (!rhub->psi) +- rhub->psi_count = 0; +- +- rhub->psi_uid_count++; +- for (i = 0; i < rhub->psi_count; i++) { +- rhub->psi[i] = readl(addr + 4 + i); ++ port_cap = &xhci->port_caps[xhci->num_port_caps++]; ++ if (xhci->num_port_caps > max_caps) ++ return; ++ ++ port_cap->maj_rev = major_revision; ++ port_cap->min_rev = minor_revision; ++ port_cap->psi_count = XHCI_EXT_PORT_PSIC(temp); ++ ++ if (port_cap->psi_count) { ++ port_cap->psi = kcalloc_node(port_cap->psi_count, ++ sizeof(*port_cap->psi), ++ GFP_KERNEL, dev_to_node(dev)); ++ if (!port_cap->psi) ++ port_cap->psi_count = 0; ++ ++ port_cap->psi_uid_count++; ++ for (i = 0; i < port_cap->psi_count; i++) { ++ port_cap->psi[i] = readl(addr + 4 + i); + + /* count unique ID values, two consecutive entries can + * have the same ID if link is assymetric + */ +- if (i && (XHCI_EXT_PORT_PSIV(rhub->psi[i]) != +- XHCI_EXT_PORT_PSIV(rhub->psi[i - 1]))) +- rhub->psi_uid_count++; ++ if (i && (XHCI_EXT_PORT_PSIV(port_cap->psi[i]) != ++ XHCI_EXT_PORT_PSIV(port_cap->psi[i - 1]))) ++ port_cap->psi_uid_count++; + + xhci_dbg(xhci, "PSIV:%d PSIE:%d PLT:%d PFD:%d LP:%d PSIM:%d\n", +- XHCI_EXT_PORT_PSIV(rhub->psi[i]), +- XHCI_EXT_PORT_PSIE(rhub->psi[i]), +- XHCI_EXT_PORT_PLT(rhub->psi[i]), +- XHCI_EXT_PORT_PFD(rhub->psi[i]), +- XHCI_EXT_PORT_LP(rhub->psi[i]), +- XHCI_EXT_PORT_PSIM(rhub->psi[i])); ++ XHCI_EXT_PORT_PSIV(port_cap->psi[i]), ++ XHCI_EXT_PORT_PSIE(port_cap->psi[i]), ++ XHCI_EXT_PORT_PLT(port_cap->psi[i]), ++ XHCI_EXT_PORT_PFD(port_cap->psi[i]), ++ XHCI_EXT_PORT_LP(port_cap->psi[i]), ++ XHCI_EXT_PORT_PSIM(port_cap->psi[i])); + } + } + /* cache usb2 port capabilities */ +@@ -2219,6 +2228,7 @@ static void xhci_add_in_port(struct xhci + continue; + } + hw_port->rhub = rhub; ++ hw_port->port_cap = port_cap; + rhub->num_ports++; + } + /* FIXME: Should we disable ports not in the Extended Capabilities? */ +@@ -2309,6 +2319,11 @@ static int xhci_setup_port_arrays(struct + if (!xhci->ext_caps) + return -ENOMEM; + ++ xhci->port_caps = kcalloc_node(cap_count, sizeof(*xhci->port_caps), ++ flags, dev_to_node(dev)); ++ if (!xhci->port_caps) ++ return -ENOMEM; ++ + offset = cap_start; + + while (offset) { +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1702,12 +1702,20 @@ struct xhci_bus_state { + * Intel Lynx Point LP xHCI host. + */ + #define XHCI_MAX_REXIT_TIMEOUT_MS 20 ++struct xhci_port_cap { ++ u32 *psi; /* array of protocol speed ID entries */ ++ u8 psi_count; ++ u8 psi_uid_count; ++ u8 maj_rev; ++ u8 min_rev; ++}; + + struct xhci_port { + __le32 __iomem *addr; + int hw_portnum; + int hcd_portnum; + struct xhci_hub *rhub; ++ struct xhci_port_cap *port_cap; + }; + + struct xhci_hub { +@@ -1719,9 +1727,6 @@ struct xhci_hub { + /* supported prococol extended capabiliy values */ + u8 maj_rev; + u8 min_rev; +- u32 *psi; /* array of protocol speed ID entries */ +- u8 psi_count; +- u8 psi_uid_count; + }; + + /* There is one xhci_hcd structure per controller */ +@@ -1880,6 +1885,9 @@ struct xhci_hcd { + /* cached usb2 extened protocol capabilites */ + u32 *ext_caps; + unsigned int num_ext_caps; ++ /* cached extended protocol port capabilities */ ++ struct xhci_port_cap *port_caps; ++ unsigned int num_port_caps; + /* Compliance Mode Recovery Data */ + struct timer_list comp_mode_recovery_timer; + u32 port_status_u0; diff --git a/queue-5.5/xhci-fix-runtime-pm-enabling-for-quirky-intel-hosts.patch b/queue-5.5/xhci-fix-runtime-pm-enabling-for-quirky-intel-hosts.patch new file mode 100644 index 00000000000..1281235161d --- /dev/null +++ b/queue-5.5/xhci-fix-runtime-pm-enabling-for-quirky-intel-hosts.patch @@ -0,0 +1,55 @@ +From 024d411e9c5d49eb96c825af52a3ce2682895676 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 10 Feb 2020 15:45:52 +0200 +Subject: xhci: fix runtime pm enabling for quirky Intel hosts + +From: Mathias Nyman + +commit 024d411e9c5d49eb96c825af52a3ce2682895676 upstream. + +Intel hosts that need the XHCI_PME_STUCK_QUIRK flag should enable +runtime pm by calling xhci_pme_acpi_rtd3_enable() before +usb_hcd_pci_probe() calls pci_dev_run_wake(). +Otherwise usage count for the device won't be decreased, and runtime +suspend is prevented. + +usb_hcd_pci_probe() only decreases the usage count if device can +generate run-time wake-up events, i.e. when pci_dev_run_wake() +returns true. + +This issue was exposed by pci_dev_run_wake() change in +commit 8feaec33b986 ("PCI / PM: Always check PME wakeup capability for +runtime wakeup support") +and should be backported to kernels with that change + +Cc: # 4.13+ +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20200210134553.9144-4-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-pci.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -302,6 +302,9 @@ static int xhci_pci_setup(struct usb_hcd + if (!usb_hcd_is_primary_hcd(hcd)) + return 0; + ++ if (xhci->quirks & XHCI_PME_STUCK_QUIRK) ++ xhci_pme_acpi_rtd3_enable(pdev); ++ + xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn); + + /* Find any debug ports */ +@@ -359,9 +362,6 @@ static int xhci_pci_probe(struct pci_dev + HCC_MAX_PSA(xhci->hcc_params) >= 4) + xhci->shared_hcd->can_do_streams = 1; + +- if (xhci->quirks & XHCI_PME_STUCK_QUIRK) +- xhci_pme_acpi_rtd3_enable(dev); +- + /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ + pm_runtime_put_noidle(&dev->dev); + diff --git a/queue-5.5/xhci-force-maximum-packet-size-for-full-speed-bulk-devices-to-valid-range.patch b/queue-5.5/xhci-force-maximum-packet-size-for-full-speed-bulk-devices-to-valid-range.patch new file mode 100644 index 00000000000..342cc4c9c80 --- /dev/null +++ b/queue-5.5/xhci-force-maximum-packet-size-for-full-speed-bulk-devices-to-valid-range.patch @@ -0,0 +1,51 @@ +From f148b9f402ef002b57bcff3964d45abc8ffb6c3f Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 10 Feb 2020 15:45:50 +0200 +Subject: xhci: Force Maximum Packet size for Full-speed bulk devices to valid range. + +From: Mathias Nyman + +commit f148b9f402ef002b57bcff3964d45abc8ffb6c3f upstream. + +A Full-speed bulk USB audio device (DJ-Tech CTRL) with a invalid Maximum +Packet Size of 4 causes a xHC "Parameter Error" at enumeration. + +This is because valid Maximum packet sizes for Full-speed bulk endpoints +are 8, 16, 32 and 64 bytes. Hosts are not required to support other values +than these. See usb 2 specs section 5.8.3 for details. + +The device starts working after forcing the maximum packet size to 8. +This is most likely the case with other devices as well, so force the +maximum packet size to a valid range. + +Cc: stable@vger.kernel.org +Reported-by: Rene D Obermueller +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20200210134553.9144-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-mem.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1475,9 +1475,15 @@ int xhci_endpoint_init(struct xhci_hcd * + /* Allow 3 retries for everything but isoc, set CErr = 3 */ + if (!usb_endpoint_xfer_isoc(&ep->desc)) + err_count = 3; +- /* Some devices get this wrong */ +- if (usb_endpoint_xfer_bulk(&ep->desc) && udev->speed == USB_SPEED_HIGH) +- max_packet = 512; ++ /* HS bulk max packet should be 512, FS bulk supports 8, 16, 32 or 64 */ ++ if (usb_endpoint_xfer_bulk(&ep->desc)) { ++ if (udev->speed == USB_SPEED_HIGH) ++ max_packet = 512; ++ if (udev->speed == USB_SPEED_FULL) { ++ max_packet = rounddown_pow_of_two(max_packet); ++ max_packet = clamp_val(max_packet, 8, 64); ++ } ++ } + /* xHCI 1.0 and 1.1 indicates that ctrl ep avg TRB Length should be 8 */ + if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100) + avg_trb_len = 8; -- 2.47.3