--- /dev/null
+From 291c566a28910614ce42d0ffe82196eddd6346f4 Mon Sep 17 00:00:00 2001
+From: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Date: Mon, 16 Jan 2017 18:31:37 +0200
+Subject: net/mlx4_core: Fix racy CQ (Completion Queue) free
+
+From: Jack Morgenstein <jackm@dev.mellanox.co.il>
+
+commit 291c566a28910614ce42d0ffe82196eddd6346f4 upstream.
+
+In function mlx4_cq_completion() and mlx4_cq_event(), the
+radix_tree_lookup requires a rcu_read_lock.
+This is mandatory: if another core frees the CQ, it could
+run the radix_tree_node_rcu_free() call_rcu() callback while
+its being used by the radix tree lookup function.
+
+Additionally, in function mlx4_cq_event(), since we are adding
+the rcu lock around the radix-tree lookup, we no longer need to take
+the spinlock. Also, the synchronize_irq() call for the async event
+eliminates the need for incrementing the cq reference count in
+mlx4_cq_event().
+
+Other changes:
+1. In function mlx4_cq_free(), replace spin_lock_irq with spin_lock:
+ we no longer take this spinlock in the interrupt context.
+ The spinlock here, therefore, simply protects against different
+ threads simultaneously invoking mlx4_cq_free() for different cq's.
+
+2. In function mlx4_cq_free(), we move the radix tree delete to before
+ the synchronize_irq() calls. This guarantees that we will not
+ access this cq during any subsequent interrupts, and therefore can
+ safely free the CQ after the synchronize_irq calls. The rcu_read_lock
+ in the interrupt handlers only needs to protect against corrupting the
+ radix tree; the interrupt handlers may access the cq outside the
+ rcu_read_lock due to the synchronize_irq calls which protect against
+ premature freeing of the cq.
+
+3. In function mlx4_cq_event(), we change the mlx_warn message to mlx4_dbg.
+
+4. We leave the cq reference count mechanism in place, because it is
+ still needed for the cq completion tasklet mechanism.
+
+Fixes: 6d90aa5cf17b ("net/mlx4_core: Make sure there are no pending async events when freeing CQ")
+Fixes: 225c7b1feef1 ("IB/mlx4: Add a driver Mellanox ConnectX InfiniBand adapters")
+Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Signed-off-by: Matan Barak <matanb@mellanox.com>
+Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlx4/cq.c | 38 ++++++++++++++++----------------
+ 1 file changed, 20 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/cq.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cq.c
+@@ -101,13 +101,19 @@ void mlx4_cq_completion(struct mlx4_dev
+ {
+ struct mlx4_cq *cq;
+
++ rcu_read_lock();
+ cq = radix_tree_lookup(&mlx4_priv(dev)->cq_table.tree,
+ cqn & (dev->caps.num_cqs - 1));
++ rcu_read_unlock();
++
+ if (!cq) {
+ mlx4_dbg(dev, "Completion event for bogus CQ %08x\n", cqn);
+ return;
+ }
+
++ /* Acessing the CQ outside of rcu_read_lock is safe, because
++ * the CQ is freed only after interrupt handling is completed.
++ */
+ ++cq->arm_sn;
+
+ cq->comp(cq);
+@@ -118,23 +124,19 @@ void mlx4_cq_event(struct mlx4_dev *dev,
+ struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table;
+ struct mlx4_cq *cq;
+
+- spin_lock(&cq_table->lock);
+-
++ rcu_read_lock();
+ cq = radix_tree_lookup(&cq_table->tree, cqn & (dev->caps.num_cqs - 1));
+- if (cq)
+- atomic_inc(&cq->refcount);
+-
+- spin_unlock(&cq_table->lock);
++ rcu_read_unlock();
+
+ if (!cq) {
+- mlx4_warn(dev, "Async event for bogus CQ %08x\n", cqn);
++ mlx4_dbg(dev, "Async event for bogus CQ %08x\n", cqn);
+ return;
+ }
+
++ /* Acessing the CQ outside of rcu_read_lock is safe, because
++ * the CQ is freed only after interrupt handling is completed.
++ */
+ cq->event(cq, event_type);
+-
+- if (atomic_dec_and_test(&cq->refcount))
+- complete(&cq->free);
+ }
+
+ static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
+@@ -301,9 +303,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev,
+ if (err)
+ return err;
+
+- spin_lock_irq(&cq_table->lock);
++ spin_lock(&cq_table->lock);
+ err = radix_tree_insert(&cq_table->tree, cq->cqn, cq);
+- spin_unlock_irq(&cq_table->lock);
++ spin_unlock(&cq_table->lock);
+ if (err)
+ goto err_icm;
+
+@@ -349,9 +351,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev,
+ return 0;
+
+ err_radix:
+- spin_lock_irq(&cq_table->lock);
++ spin_lock(&cq_table->lock);
+ radix_tree_delete(&cq_table->tree, cq->cqn);
+- spin_unlock_irq(&cq_table->lock);
++ spin_unlock(&cq_table->lock);
+
+ err_icm:
+ mlx4_cq_free_icm(dev, cq->cqn);
+@@ -370,15 +372,15 @@ void mlx4_cq_free(struct mlx4_dev *dev,
+ if (err)
+ mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn);
+
++ spin_lock(&cq_table->lock);
++ radix_tree_delete(&cq_table->tree, cq->cqn);
++ spin_unlock(&cq_table->lock);
++
+ synchronize_irq(priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq);
+ if (priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq !=
+ priv->eq_table.eq[MLX4_EQ_ASYNC].irq)
+ synchronize_irq(priv->eq_table.eq[MLX4_EQ_ASYNC].irq);
+
+- spin_lock_irq(&cq_table->lock);
+- radix_tree_delete(&cq_table->tree, cq->cqn);
+- spin_unlock_irq(&cq_table->lock);
+-
+ if (atomic_dec_and_test(&cq->refcount))
+ complete(&cq->free);
+ wait_for_completion(&cq->free);
--- /dev/null
+From 7c3945bc2073554bb2ecf983e073dee686679c53 Mon Sep 17 00:00:00 2001
+From: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Date: Mon, 16 Jan 2017 18:31:38 +0200
+Subject: net/mlx4_core: Fix when to save some qp context flags for dynamic VST to VGT transitions
+
+From: Jack Morgenstein <jackm@dev.mellanox.co.il>
+
+commit 7c3945bc2073554bb2ecf983e073dee686679c53 upstream.
+
+Save the qp context flags byte containing the flag disabling vlan stripping
+in the RESET to INIT qp transition, rather than in the INIT to RTR
+transition. Per the firmware spec, the flags in this byte are active
+in the RESET to INIT transition.
+
+As a result of saving the flags in the incorrect qp transition, when
+switching dynamically from VGT to VST and back to VGT, the vlan
+remained stripped (as is required for VST) and did not return to
+not-stripped (as is required for VGT).
+
+Fixes: f0f829bf42cd ("net/mlx4_core: Add immediate activate for VGT->VST->VGT")
+Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
++++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+@@ -2980,6 +2980,9 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4
+ put_res(dev, slave, srqn, RES_SRQ);
+ qp->srq = srq;
+ }
++
++ /* Save param3 for dynamic changes from VST back to VGT */
++ qp->param3 = qpc->param3;
+ put_res(dev, slave, rcqn, RES_CQ);
+ put_res(dev, slave, mtt_base, RES_MTT);
+ res_end_move(dev, slave, RES_QP, qpn);
+@@ -3772,7 +3775,6 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4
+ int qpn = vhcr->in_modifier & 0x7fffff;
+ struct res_qp *qp;
+ u8 orig_sched_queue;
+- __be32 orig_param3 = qpc->param3;
+ u8 orig_vlan_control = qpc->pri_path.vlan_control;
+ u8 orig_fvl_rx = qpc->pri_path.fvl_rx;
+ u8 orig_pri_path_fl = qpc->pri_path.fl;
+@@ -3814,7 +3816,6 @@ out:
+ */
+ if (!err) {
+ qp->sched_queue = orig_sched_queue;
+- qp->param3 = orig_param3;
+ qp->vlan_control = orig_vlan_control;
+ qp->fvl_rx = orig_fvl_rx;
+ qp->pri_path_fl = orig_pri_path_fl;
--- /dev/null
+From 6496bbf0ec481966ef9ffe5b6660d8d1b55c60cc Mon Sep 17 00:00:00 2001
+From: Eugenia Emantayev <eugenia@mellanox.com>
+Date: Thu, 29 Dec 2016 18:37:10 +0200
+Subject: net/mlx4_en: Fix bad WQE issue
+
+From: Eugenia Emantayev <eugenia@mellanox.com>
+
+commit 6496bbf0ec481966ef9ffe5b6660d8d1b55c60cc upstream.
+
+Single send WQE in RX buffer should be stamped with software
+ownership in order to prevent the flow of QP in error in FW
+once UPDATE_QP is called.
+
+Fixes: 9f519f68cfff ('mlx4_en: Not using Shared Receive Queues')
+Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
+Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlx4/en_rx.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+@@ -444,8 +444,14 @@ int mlx4_en_activate_rx_rings(struct mlx
+ ring->cqn = priv->rx_cq[ring_ind]->mcq.cqn;
+
+ ring->stride = stride;
+- if (ring->stride <= TXBB_SIZE)
++ if (ring->stride <= TXBB_SIZE) {
++ /* Stamp first unused send wqe */
++ __be32 *ptr = (__be32 *)ring->buf;
++ __be32 stamp = cpu_to_be32(1 << STAMP_SHIFT);
++ *ptr = stamp;
++ /* Move pointer to start of rx section */
+ ring->buf += TXBB_SIZE;
++ }
+
+ ring->log_stride = ffs(ring->stride) - 1;
+ ring->buf_size = ring->size * ring->stride;
revert-drm-i915-execlists-reset-ring-registers-upon-resume.patch
net-packet-fix-overflow-in-check-for-priv-area-size.patch
blk-mq-avoid-memory-reclaim-when-remapping-queues.patch
+usb-hub-wait-for-connection-to-be-reestablished-after-port-reset.patch
+net-mlx4_en-fix-bad-wqe-issue.patch
+net-mlx4_core-fix-racy-cq-completion-queue-free.patch
+net-mlx4_core-fix-when-to-save-some-qp-context-flags-for-dynamic-vst-to-vgt-transitions.patch
--- /dev/null
+From 22547c4cc4fe20698a6a85a55b8788859134b8e4 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Thu, 1 Dec 2016 13:49:59 -0800
+Subject: usb: hub: Wait for connection to be reestablished after port reset
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit 22547c4cc4fe20698a6a85a55b8788859134b8e4 upstream.
+
+On a system with a defective USB device connected to an USB hub,
+an endless sequence of port connect events was observed. The sequence
+of events as observed is as follows:
+
+- Port reports connected event (port status=USB_PORT_STAT_CONNECTION).
+- Event handler debounces port and resets it by calling hub_port_reset().
+- hub_port_reset() calls hub_port_wait_reset() to wait for the reset
+ to complete.
+- The reset completes, but USB_PORT_STAT_CONNECTION is not immediately
+ set in the port status register.
+- hub_port_wait_reset() returns -ENOTCONN.
+- Port initialization sequence is aborted.
+- A few milliseconds later, the port again reports a connected event,
+ and the sequence repeats.
+
+This continues either forever or, randomly, stops if the connection
+is already re-established when the port status is read. It results in
+a high rate of udev events. This in turn destabilizes userspace since
+the above sequence holds the device mutex pretty much continuously
+and prevents userspace from actually reading the device status.
+
+To prevent the problem from happening, let's wait for the connection
+to be re-established after a port reset. If the device was actually
+disconnected, the code will still return an error, but it will do so
+only after the long reset timeout.
+
+Cc: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2650,8 +2650,15 @@ static int hub_port_wait_reset(struct us
+ if (ret < 0)
+ return ret;
+
+- /* The port state is unknown until the reset completes. */
+- if (!(portstatus & USB_PORT_STAT_RESET))
++ /*
++ * The port state is unknown until the reset completes.
++ *
++ * On top of that, some chips may require additional time
++ * to re-establish a connection after the reset is complete,
++ * so also wait for the connection to be re-established.
++ */
++ if (!(portstatus & USB_PORT_STAT_RESET) &&
++ (portstatus & USB_PORT_STAT_CONNECTION))
+ break;
+
+ /* switch to the long delay after two short delay failures */