From: Greg Kroah-Hartman Date: Wed, 28 Nov 2018 13:10:59 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.19.6~47 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d8608a0161473b7371b08788222ca02f839becc0;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: ib-core-perform-modify-qp-on-real-one.patch usb-xhci-prevent-bus-suspend-if-a-port-connect-change-or-polling-state-is-detected.patch --- diff --git a/queue-4.14/ib-core-perform-modify-qp-on-real-one.patch b/queue-4.14/ib-core-perform-modify-qp-on-real-one.patch new file mode 100644 index 00000000000..87787e97076 --- /dev/null +++ b/queue-4.14/ib-core-perform-modify-qp-on-real-one.patch @@ -0,0 +1,50 @@ +From b2bedfb39541a7e14798d066b6f8685d84c8fcf5 Mon Sep 17 00:00:00 2001 +From: Parav Pandit +Date: Tue, 9 Jan 2018 15:24:50 +0200 +Subject: IB/core: Perform modify QP on real one + +From: Parav Pandit + +commit b2bedfb39541a7e14798d066b6f8685d84c8fcf5 upstream. + +Currently qp->port stores the port number whenever IB_QP_PORT +QP attribute mask is set (during QP state transition to INIT state). +This port number should be stored for the real QP when XRC target QP +is used. + +Follow the ib_modify_qp() implementation and hide the access to ->real_qp. + +Fixes: a512c2fbef9c ("IB/core: Introduce modify QP operation with udata") +Signed-off-by: Parav Pandit +Reviewed-by: Daniel Jurgens +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/verbs.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/core/verbs.c ++++ b/drivers/infiniband/core/verbs.c +@@ -1285,7 +1285,7 @@ EXPORT_SYMBOL(ib_resolve_eth_dmac); + + /** + * ib_modify_qp_with_udata - Modifies the attributes for the specified QP. +- * @qp: The QP to modify. ++ * @ib_qp: The QP to modify. + * @attr: On input, specifies the QP attributes to modify. On output, + * the current values of selected QP attributes are returned. + * @attr_mask: A bit-mask used to specify which attributes of the QP +@@ -1294,9 +1294,10 @@ EXPORT_SYMBOL(ib_resolve_eth_dmac); + * are being modified. + * It returns 0 on success and returns appropriate error code on error. + */ +-int ib_modify_qp_with_udata(struct ib_qp *qp, struct ib_qp_attr *attr, ++int ib_modify_qp_with_udata(struct ib_qp *ib_qp, struct ib_qp_attr *attr, + int attr_mask, struct ib_udata *udata) + { ++ struct ib_qp *qp = ib_qp->real_qp; + int ret; + + if (attr_mask & IB_QP_AV) { diff --git a/queue-4.14/series b/queue-4.14/series index 6a230767794..8606a195641 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -28,6 +28,8 @@ llc-do-not-use-sk_eat_skb.patch mm-don-t-warn-about-large-allocations-for-slab.patch mm-memory.c-recheck-page-table-entry-with-page-table-lock-held.patch tcp-do-not-release-socket-ownership-in-tcp_close.patch +ib-core-perform-modify-qp-on-real-one.patch +usb-xhci-prevent-bus-suspend-if-a-port-connect-change-or-polling-state-is-detected.patch drm-ast-change-resolution-may-cause-screen-blurred.patch drm-ast-fixed-cursor-may-disappear-sometimes.patch drm-ast-remove-existing-framebuffers-before-loading-driver.patch diff --git a/queue-4.14/usb-xhci-prevent-bus-suspend-if-a-port-connect-change-or-polling-state-is-detected.patch b/queue-4.14/usb-xhci-prevent-bus-suspend-if-a-port-connect-change-or-polling-state-is-detected.patch new file mode 100644 index 00000000000..2727f6b3708 --- /dev/null +++ b/queue-4.14/usb-xhci-prevent-bus-suspend-if-a-port-connect-change-or-polling-state-is-detected.patch @@ -0,0 +1,146 @@ +From 2f31a67f01a8beb22cae754c53522cb61a005750 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 15 Nov 2018 11:38:41 +0200 +Subject: usb: xhci: Prevent bus suspend if a port connect change or polling state is detected + +From: Mathias Nyman + +commit 2f31a67f01a8beb22cae754c53522cb61a005750 upstream. + +USB3 roothub might autosuspend before a plugged USB3 device is detected, +causing USB3 device enumeration failure. + +USB3 devices don't show up as connected and enabled until USB3 link trainig +completes. On a fast booting platform with a slow USB3 link training the +link might reach the connected enabled state just as the bus is suspending. + +If this device is discovered first time by the xhci_bus_suspend() routine +it will be put to U3 suspended state like the other ports which failed to +suspend earlier. + +The hub thread will notice the connect change and resume the bus, +moving the port back to U0 + +This U0 -> U3 -> U0 transition right after being connected seems to be +too much for some devices, causing them to first go to SS.Inactive state, +and finally end up stuck in a polling state with reset asserted + +Fix this by failing the bus suspend if a port has a connect change or is +in a polling state in xhci_bus_suspend(). + +Don't do any port changes until all ports are checked, buffer all port +changes and only write them in the end if suspend can proceed + +Cc: stable@vger.kernel.org +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-hub.c | 60 +++++++++++++++++++++++++++++++++----------- + 1 file changed, 46 insertions(+), 14 deletions(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -1481,13 +1481,16 @@ int xhci_bus_suspend(struct usb_hcd *hcd + __le32 __iomem **port_array; + struct xhci_bus_state *bus_state; + unsigned long flags; ++ u32 portsc_buf[USB_MAXCHILDREN]; ++ bool wake_enabled; + + max_ports = xhci_get_ports(hcd, &port_array); + bus_state = &xhci->bus_state[hcd_index(hcd)]; ++ wake_enabled = hcd->self.root_hub->do_remote_wakeup; + + spin_lock_irqsave(&xhci->lock, flags); + +- if (hcd->self.root_hub->do_remote_wakeup) { ++ if (wake_enabled) { + if (bus_state->resuming_ports || /* USB2 */ + bus_state->port_remote_wakeup) { /* USB3 */ + spin_unlock_irqrestore(&xhci->lock, flags); +@@ -1495,26 +1498,36 @@ int xhci_bus_suspend(struct usb_hcd *hcd + return -EBUSY; + } + } +- +- port_index = max_ports; ++ /* ++ * Prepare ports for suspend, but don't write anything before all ports ++ * are checked and we know bus suspend can proceed ++ */ + bus_state->bus_suspended = 0; ++ port_index = max_ports; + while (port_index--) { +- /* suspend the port if the port is not suspended */ + u32 t1, t2; +- int slot_id; + + t1 = readl(port_array[port_index]); + t2 = xhci_port_state_to_neutral(t1); ++ portsc_buf[port_index] = 0; + +- if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) { +- xhci_dbg(xhci, "port %d not suspended\n", port_index); +- slot_id = xhci_find_slot_id_by_port(hcd, xhci, +- port_index + 1); +- if (slot_id) { ++ /* Bail out if a USB3 port has a new device in link training */ ++ if ((t1 & PORT_PLS_MASK) == XDEV_POLLING) { ++ bus_state->bus_suspended = 0; ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ xhci_dbg(xhci, "Bus suspend bailout, port in polling\n"); ++ return -EBUSY; ++ } ++ ++ /* suspend ports in U0, or bail out for new connect changes */ ++ if ((t1 & PORT_PE) && (t1 & PORT_PLS_MASK) == XDEV_U0) { ++ if ((t1 & PORT_CSC) && wake_enabled) { ++ bus_state->bus_suspended = 0; + spin_unlock_irqrestore(&xhci->lock, flags); +- xhci_stop_device(xhci, slot_id, 1); +- spin_lock_irqsave(&xhci->lock, flags); ++ xhci_dbg(xhci, "Bus suspend bailout, port connect change\n"); ++ return -EBUSY; + } ++ xhci_dbg(xhci, "port %d not suspended\n", port_index); + t2 &= ~PORT_PLS_MASK; + t2 |= PORT_LINK_STROBE | XDEV_U3; + set_bit(port_index, &bus_state->bus_suspended); +@@ -1523,7 +1536,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd + * including the USB 3.0 roothub, but only if CONFIG_PM + * is enabled, so also enable remote wake here. + */ +- if (hcd->self.root_hub->do_remote_wakeup) { ++ if (wake_enabled) { + if (t1 & PORT_CONNECT) { + t2 |= PORT_WKOC_E | PORT_WKDISC_E; + t2 &= ~PORT_WKCONN_E; +@@ -1543,7 +1556,26 @@ int xhci_bus_suspend(struct usb_hcd *hcd + + t1 = xhci_port_state_to_neutral(t1); + if (t1 != t2) +- writel(t2, port_array[port_index]); ++ portsc_buf[port_index] = t2; ++ } ++ ++ /* write port settings, stopping and suspending ports if needed */ ++ port_index = max_ports; ++ while (port_index--) { ++ if (!portsc_buf[port_index]) ++ continue; ++ if (test_bit(port_index, &bus_state->bus_suspended)) { ++ int slot_id; ++ ++ slot_id = xhci_find_slot_id_by_port(hcd, xhci, ++ port_index + 1); ++ if (slot_id) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ xhci_stop_device(xhci, slot_id, 1); ++ spin_lock_irqsave(&xhci->lock, flags); ++ } ++ } ++ writel(portsc_buf[port_index], port_array[port_index]); + } + hcd->state = HC_STATE_SUSPENDED; + bus_state->next_statechange = jiffies + msecs_to_jiffies(10);