From: Greg Kroah-Hartman Date: Mon, 21 Nov 2016 16:29:27 +0000 (+0100) Subject: 4.8-stable patches X-Git-Tag: v4.4.35~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f1ee1543dba96a78d61557a463c3c2766453f5b4;p=thirdparty%2Fkernel%2Fstable-queue.git 4.8-stable patches added patches: clk-imx-fix-integer-overflow-in-av-pll-round-rate.patch clk-mmp-mmp2-fix-return-value-check-in-mmp2_clk_init.patch clk-mmp-pxa168-fix-return-value-check-in-pxa168_clk_init.patch clk-mmp-pxa910-fix-return-value-check-in-pxa910_clk_init.patch ib-cm-mark-stale-cm-id-s-whenever-the-mad-agent-was-unregistered.patch ib-core-avoid-unsigned-int-overflow-in-sg_alloc_table.patch ib-hfi1-remove-incorrect-is_err-check.patch ib-mlx4-check-gid_index-return-value.patch ib-mlx4-fix-create-cq-error-flow.patch ib-mlx5-fix-fatal-error-dispatching.patch ib-mlx5-fix-memory-leak-in-query-device.patch ib-mlx5-fix-null-pointer-dereference-on-debug-print.patch ib-mlx5-use-cache-line-size-to-select-cqe-stride.patch ib-mlx5-validate-requested-rqt-size.patch ib-rxe-clear-queue-buffer-when-modifying-qp-to-reset.patch ib-rxe-fix-handling-of-erroneous-wr.patch ib-rxe-fix-kernel-panic-in-udp-tunnel-with-gro-and-rx-checksum.patch ib-rxe-update-qp-state-for-user-query.patch ib-uverbs-fix-leak-of-xrc-target-qps.patch iwlwifi-mvm-fix-d3_test-with-unified-d0-d3-images.patch iwlwifi-mvm-fix-netdetect-starting-stopping-for-unified-images.patch iwlwifi-mvm-wake-the-wait-queue-when-the-rx-sync-counter-is-zero.patch iwlwifi-pcie-fix-splc-structure-parsing.patch iwlwifi-pcie-mark-command-queue-lock-with-separate-lockdep-class.patch mfd-core-fix-device-reference-leak-in-mfd_clone_cell.patch netfilter-nft_dynset-fix-element-timeout-for-hz-1000.patch perf-hists-fix-column-length-on-hierarchy.patch pm-sleep-don-t-suspend-parent-when-async-child-suspend_-noirq-late-fails.patch pm-sleep-fix-device-reference-leak-in-test_suspend.patch rtc-omap-fix-selecting-external-osc.patch sunrpc-svc_age_temp_xprts_now-should-not-call-setsockopt-non-tcp-transports.patch uwb-fix-device-reference-leaks.patch --- diff --git a/queue-4.8/clk-imx-fix-integer-overflow-in-av-pll-round-rate.patch b/queue-4.8/clk-imx-fix-integer-overflow-in-av-pll-round-rate.patch new file mode 100644 index 00000000000..2e7597aa98d --- /dev/null +++ b/queue-4.8/clk-imx-fix-integer-overflow-in-av-pll-round-rate.patch @@ -0,0 +1,53 @@ +From 5c2f117a22e46a4afee6ddee29b653a7a2a6b41f Mon Sep 17 00:00:00 2001 +From: Emil Lundmark +Date: Wed, 12 Oct 2016 12:31:40 +0200 +Subject: clk: imx: fix integer overflow in AV PLL round rate + +From: Emil Lundmark + +commit 5c2f117a22e46a4afee6ddee29b653a7a2a6b41f upstream. + +Since 'parent_rate * mfn' may overflow 32 bits, the result should be +stored using 64 bits. + +The problem was discovered when trying to set the rate of the audio PLL +(pll4_post_div) on an i.MX6Q. The desired rate was 196.608 MHz, but +the actual rate returned was 192.000570 MHz. The round rate function should +have been able to return 196.608 MHz, i.e., the desired rate. + +Fixes: ba7f4f557eb6 ("clk: imx: correct AV PLL rate formula") +Cc: Anson Huang +Signed-off-by: Emil Lundmark +Reviewed-by: Fabio Estevam +Acked-by: Shawn Guo +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/imx/clk-pllv3.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/clk/imx/clk-pllv3.c ++++ b/drivers/clk/imx/clk-pllv3.c +@@ -223,7 +223,7 @@ static unsigned long clk_pllv3_av_recalc + temp64 *= mfn; + do_div(temp64, mfd); + +- return (parent_rate * div) + (u32)temp64; ++ return parent_rate * div + (unsigned long)temp64; + } + + static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, +@@ -247,7 +247,11 @@ static long clk_pllv3_av_round_rate(stru + do_div(temp64, parent_rate); + mfn = temp64; + +- return parent_rate * div + parent_rate * mfn / mfd; ++ temp64 = (u64)parent_rate; ++ temp64 *= mfn; ++ do_div(temp64, mfd); ++ ++ return parent_rate * div + (unsigned long)temp64; + } + + static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/queue-4.8/clk-mmp-mmp2-fix-return-value-check-in-mmp2_clk_init.patch b/queue-4.8/clk-mmp-mmp2-fix-return-value-check-in-mmp2_clk_init.patch new file mode 100644 index 00000000000..e89f3ecafd6 --- /dev/null +++ b/queue-4.8/clk-mmp-mmp2-fix-return-value-check-in-mmp2_clk_init.patch @@ -0,0 +1,32 @@ +From a29e52a6e66f4c0c895e7083e4bad2e7957f1fb5 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Sat, 17 Sep 2016 15:54:13 +0000 +Subject: clk: mmp: mmp2: fix return value check in mmp2_clk_init() + +From: Wei Yongjun + +commit a29e52a6e66f4c0c895e7083e4bad2e7957f1fb5 upstream. + +Fix the retrn value check which testing the wrong variable +in mmp2_clk_init(). + +Fixes: 1ec770d92a62 ("clk: mmp: add mmp2 DT support for clock driver") +Signed-off-by: Wei Yongjun +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/mmp/clk-of-mmp2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/clk/mmp/clk-of-mmp2.c ++++ b/drivers/clk/mmp/clk-of-mmp2.c +@@ -313,7 +313,7 @@ static void __init mmp2_clk_init(struct + } + + pxa_unit->apmu_base = of_iomap(np, 1); +- if (!pxa_unit->mpmu_base) { ++ if (!pxa_unit->apmu_base) { + pr_err("failed to map apmu registers\n"); + return; + } diff --git a/queue-4.8/clk-mmp-pxa168-fix-return-value-check-in-pxa168_clk_init.patch b/queue-4.8/clk-mmp-pxa168-fix-return-value-check-in-pxa168_clk_init.patch new file mode 100644 index 00000000000..1c484c40c99 --- /dev/null +++ b/queue-4.8/clk-mmp-pxa168-fix-return-value-check-in-pxa168_clk_init.patch @@ -0,0 +1,32 @@ +From deab07261d54b4db7b627d38e0efac97f176c6d6 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Sat, 17 Sep 2016 15:54:28 +0000 +Subject: clk: mmp: pxa168: fix return value check in pxa168_clk_init() + +From: Wei Yongjun + +commit deab07261d54b4db7b627d38e0efac97f176c6d6 upstream. + +Fix the retrn value check which testing the wrong variable +in pxa168_clk_init(). + +Fixes: ab08aefcd12d ("clk: mmp: add pxa168 DT support for clock driver") +Signed-off-by: Wei Yongjun +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/mmp/clk-of-pxa168.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/clk/mmp/clk-of-pxa168.c ++++ b/drivers/clk/mmp/clk-of-pxa168.c +@@ -262,7 +262,7 @@ static void __init pxa168_clk_init(struc + } + + pxa_unit->apmu_base = of_iomap(np, 1); +- if (!pxa_unit->mpmu_base) { ++ if (!pxa_unit->apmu_base) { + pr_err("failed to map apmu registers\n"); + return; + } diff --git a/queue-4.8/clk-mmp-pxa910-fix-return-value-check-in-pxa910_clk_init.patch b/queue-4.8/clk-mmp-pxa910-fix-return-value-check-in-pxa910_clk_init.patch new file mode 100644 index 00000000000..271731d64ab --- /dev/null +++ b/queue-4.8/clk-mmp-pxa910-fix-return-value-check-in-pxa910_clk_init.patch @@ -0,0 +1,41 @@ +From 10f2bfb092e3b49000526c02cfe8b2abbbdbb752 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Sat, 17 Sep 2016 15:55:56 +0000 +Subject: clk: mmp: pxa910: fix return value check in pxa910_clk_init() + +From: Wei Yongjun + +commit 10f2bfb092e3b49000526c02cfe8b2abbbdbb752 upstream. + +Fix the retrn value check which testing the wrong variable +in pxa910_clk_init(). + +Fixes: 2bc61da9f7ff ("clk: mmp: add pxa910 DT support for clock driver") +Signed-off-by: Wei Yongjun +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/mmp/clk-of-pxa910.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/clk/mmp/clk-of-pxa910.c ++++ b/drivers/clk/mmp/clk-of-pxa910.c +@@ -282,7 +282,7 @@ static void __init pxa910_clk_init(struc + } + + pxa_unit->apmu_base = of_iomap(np, 1); +- if (!pxa_unit->mpmu_base) { ++ if (!pxa_unit->apmu_base) { + pr_err("failed to map apmu registers\n"); + return; + } +@@ -294,7 +294,7 @@ static void __init pxa910_clk_init(struc + } + + pxa_unit->apbcp_base = of_iomap(np, 3); +- if (!pxa_unit->mpmu_base) { ++ if (!pxa_unit->apbcp_base) { + pr_err("failed to map apbcp registers\n"); + return; + } diff --git a/queue-4.8/ib-cm-mark-stale-cm-id-s-whenever-the-mad-agent-was-unregistered.patch b/queue-4.8/ib-cm-mark-stale-cm-id-s-whenever-the-mad-agent-was-unregistered.patch new file mode 100644 index 00000000000..6ad53af084d --- /dev/null +++ b/queue-4.8/ib-cm-mark-stale-cm-id-s-whenever-the-mad-agent-was-unregistered.patch @@ -0,0 +1,359 @@ +From 9db0ff53cb9b43ed75bacd42a89c1a0ab048b2b0 Mon Sep 17 00:00:00 2001 +From: Mark Bloch +Date: Thu, 27 Oct 2016 16:36:27 +0300 +Subject: IB/cm: Mark stale CM id's whenever the mad agent was unregistered + +From: Mark Bloch + +commit 9db0ff53cb9b43ed75bacd42a89c1a0ab048b2b0 upstream. + +When there is a CM id object that has port assigned to it, it means that +the cm-id asked for the specific port that it should go by it, but if +that port was removed (hot-unplug event) the cm-id was not updated. +In order to fix that the port keeps a list of all the cm-id's that are +planning to go by it, whenever the port is removed it marks all of them +as invalid. + +This commit fixes a kernel panic which happens when running traffic between +guests and we force reboot a guest mid traffic, it triggers a kernel panic: + + Call Trace: + [] ? panic+0xa7/0x16f + [] ? oops_end+0xe4/0x100 + [] ? no_context+0xfb/0x260 + [] ? del_timer_sync+0x22/0x30 + [] ? __bad_area_nosemaphore+0x125/0x1e0 + [] ? process_timeout+0x0/0x10 + [] ? bad_area_nosemaphore+0x13/0x20 + [] ? __do_page_fault+0x31f/0x480 + [] ? default_wake_function+0x0/0x20 + [] ? free_msg+0x55/0x70 [mlx5_core] + [] ? cmd_exec+0x124/0x840 [mlx5_core] + [] ? find_busiest_group+0x244/0x9f0 + [] ? do_page_fault+0x3e/0xa0 + [] ? page_fault+0x25/0x30 + [] ? cm_alloc_msg+0x35/0xc0 [ib_cm] + [] ? ib_send_cm_dreq+0xb1/0x1e0 [ib_cm] + [] ? cm_destroy_id+0x176/0x320 [ib_cm] + [] ? ib_destroy_cm_id+0x10/0x20 [ib_cm] + [] ? ipoib_cm_free_rx_reap_list+0xa7/0x110 [ib_ipoib] + [] ? ipoib_cm_rx_reap+0x0/0x20 [ib_ipoib] + [] ? ipoib_cm_rx_reap+0x15/0x20 [ib_ipoib] + [] ? worker_thread+0x170/0x2a0 + [] ? autoremove_wake_function+0x0/0x40 + [] ? worker_thread+0x0/0x2a0 + [] ? kthread+0x96/0xa0 + [] ? child_rip+0xa/0x20 + [] ? kthread+0x0/0xa0 + [] ? child_rip+0x0/0x20 + +Fixes: a977049dacde ("[PATCH] IB: Add the kernel CM implementation") +Signed-off-by: Mark Bloch +Signed-off-by: Erez Shitrit +Reviewed-by: Maor Gottlieb +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/cm.c | 126 +++++++++++++++++++++++++++++++++++++------ + 1 file changed, 110 insertions(+), 16 deletions(-) + +--- a/drivers/infiniband/core/cm.c ++++ b/drivers/infiniband/core/cm.c +@@ -80,6 +80,8 @@ static struct ib_cm { + __be32 random_id_operand; + struct list_head timewait_list; + struct workqueue_struct *wq; ++ /* Sync on cm change port state */ ++ spinlock_t state_lock; + } cm; + + /* Counter indexes ordered by attribute ID */ +@@ -161,6 +163,8 @@ struct cm_port { + struct ib_mad_agent *mad_agent; + struct kobject port_obj; + u8 port_num; ++ struct list_head cm_priv_prim_list; ++ struct list_head cm_priv_altr_list; + struct cm_counter_group counter_group[CM_COUNTER_GROUPS]; + }; + +@@ -241,6 +245,12 @@ struct cm_id_private { + u8 service_timeout; + u8 target_ack_delay; + ++ struct list_head prim_list; ++ struct list_head altr_list; ++ /* Indicates that the send port mad is registered and av is set */ ++ int prim_send_port_not_ready; ++ int altr_send_port_not_ready; ++ + struct list_head work_list; + atomic_t work_count; + }; +@@ -259,20 +269,47 @@ static int cm_alloc_msg(struct cm_id_pri + struct ib_mad_agent *mad_agent; + struct ib_mad_send_buf *m; + struct ib_ah *ah; ++ struct cm_av *av; ++ unsigned long flags, flags2; ++ int ret = 0; + ++ /* don't let the port to be released till the agent is down */ ++ spin_lock_irqsave(&cm.state_lock, flags2); ++ spin_lock_irqsave(&cm.lock, flags); ++ if (!cm_id_priv->prim_send_port_not_ready) ++ av = &cm_id_priv->av; ++ else if (!cm_id_priv->altr_send_port_not_ready && ++ (cm_id_priv->alt_av.port)) ++ av = &cm_id_priv->alt_av; ++ else { ++ pr_info("%s: not valid CM id\n", __func__); ++ ret = -ENODEV; ++ spin_unlock_irqrestore(&cm.lock, flags); ++ goto out; ++ } ++ spin_unlock_irqrestore(&cm.lock, flags); ++ /* Make sure the port haven't released the mad yet */ + mad_agent = cm_id_priv->av.port->mad_agent; +- ah = ib_create_ah(mad_agent->qp->pd, &cm_id_priv->av.ah_attr); +- if (IS_ERR(ah)) +- return PTR_ERR(ah); ++ if (!mad_agent) { ++ pr_info("%s: not a valid MAD agent\n", __func__); ++ ret = -ENODEV; ++ goto out; ++ } ++ ah = ib_create_ah(mad_agent->qp->pd, &av->ah_attr); ++ if (IS_ERR(ah)) { ++ ret = PTR_ERR(ah); ++ goto out; ++ } + + m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn, +- cm_id_priv->av.pkey_index, ++ av->pkey_index, + 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, + GFP_ATOMIC, + IB_MGMT_BASE_VERSION); + if (IS_ERR(m)) { + ib_destroy_ah(ah); +- return PTR_ERR(m); ++ ret = PTR_ERR(m); ++ goto out; + } + + /* Timeout set by caller if response is expected. */ +@@ -282,7 +319,10 @@ static int cm_alloc_msg(struct cm_id_pri + atomic_inc(&cm_id_priv->refcount); + m->context[0] = cm_id_priv; + *msg = m; +- return 0; ++ ++out: ++ spin_unlock_irqrestore(&cm.state_lock, flags2); ++ return ret; + } + + static int cm_alloc_response_msg(struct cm_port *port, +@@ -352,7 +392,8 @@ static void cm_init_av_for_response(stru + grh, &av->ah_attr); + } + +-static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av) ++static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av, ++ struct cm_id_private *cm_id_priv) + { + struct cm_device *cm_dev; + struct cm_port *port = NULL; +@@ -387,7 +428,17 @@ static int cm_init_av_by_path(struct ib_ + &av->ah_attr); + av->timeout = path->packet_life_time + 1; + +- return 0; ++ spin_lock_irqsave(&cm.lock, flags); ++ if (&cm_id_priv->av == av) ++ list_add_tail(&cm_id_priv->prim_list, &port->cm_priv_prim_list); ++ else if (&cm_id_priv->alt_av == av) ++ list_add_tail(&cm_id_priv->altr_list, &port->cm_priv_altr_list); ++ else ++ ret = -EINVAL; ++ ++ spin_unlock_irqrestore(&cm.lock, flags); ++ ++ return ret; + } + + static int cm_alloc_id(struct cm_id_private *cm_id_priv) +@@ -677,6 +728,8 @@ struct ib_cm_id *ib_create_cm_id(struct + spin_lock_init(&cm_id_priv->lock); + init_completion(&cm_id_priv->comp); + INIT_LIST_HEAD(&cm_id_priv->work_list); ++ INIT_LIST_HEAD(&cm_id_priv->prim_list); ++ INIT_LIST_HEAD(&cm_id_priv->altr_list); + atomic_set(&cm_id_priv->work_count, -1); + atomic_set(&cm_id_priv->refcount, 1); + return &cm_id_priv->id; +@@ -892,6 +945,15 @@ retest: + break; + } + ++ spin_lock_irq(&cm.lock); ++ if (!list_empty(&cm_id_priv->altr_list) && ++ (!cm_id_priv->altr_send_port_not_ready)) ++ list_del(&cm_id_priv->altr_list); ++ if (!list_empty(&cm_id_priv->prim_list) && ++ (!cm_id_priv->prim_send_port_not_ready)) ++ list_del(&cm_id_priv->prim_list); ++ spin_unlock_irq(&cm.lock); ++ + cm_free_id(cm_id->local_id); + cm_deref_id(cm_id_priv); + wait_for_completion(&cm_id_priv->comp); +@@ -1192,12 +1254,13 @@ int ib_send_cm_req(struct ib_cm_id *cm_i + goto out; + } + +- ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av); ++ ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av, ++ cm_id_priv); + if (ret) + goto error1; + if (param->alternate_path) { + ret = cm_init_av_by_path(param->alternate_path, +- &cm_id_priv->alt_av); ++ &cm_id_priv->alt_av, cm_id_priv); + if (ret) + goto error1; + } +@@ -1653,7 +1716,8 @@ static int cm_req_handler(struct cm_work + dev_put(gid_attr.ndev); + } + work->path[0].gid_type = gid_attr.gid_type; +- ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av); ++ ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av, ++ cm_id_priv); + } + if (ret) { + int err = ib_get_cached_gid(work->port->cm_dev->ib_device, +@@ -1672,7 +1736,8 @@ static int cm_req_handler(struct cm_work + goto rejected; + } + if (req_msg->alt_local_lid) { +- ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av); ++ ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av, ++ cm_id_priv); + if (ret) { + ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_ALT_GID, + &work->path[0].sgid, +@@ -2727,7 +2792,8 @@ int ib_send_cm_lap(struct ib_cm_id *cm_i + goto out; + } + +- ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av); ++ ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av, ++ cm_id_priv); + if (ret) + goto out; + cm_id_priv->alt_av.timeout = +@@ -2839,7 +2905,8 @@ static int cm_lap_handler(struct cm_work + cm_init_av_for_response(work->port, work->mad_recv_wc->wc, + work->mad_recv_wc->recv_buf.grh, + &cm_id_priv->av); +- cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av); ++ cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av, ++ cm_id_priv); + ret = atomic_inc_and_test(&cm_id_priv->work_count); + if (!ret) + list_add_tail(&work->list, &cm_id_priv->work_list); +@@ -3031,7 +3098,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id + return -EINVAL; + + cm_id_priv = container_of(cm_id, struct cm_id_private, id); +- ret = cm_init_av_by_path(param->path, &cm_id_priv->av); ++ ret = cm_init_av_by_path(param->path, &cm_id_priv->av, cm_id_priv); + if (ret) + goto out; + +@@ -3468,7 +3535,9 @@ out: + static int cm_migrate(struct ib_cm_id *cm_id) + { + struct cm_id_private *cm_id_priv; ++ struct cm_av tmp_av; + unsigned long flags; ++ int tmp_send_port_not_ready; + int ret = 0; + + cm_id_priv = container_of(cm_id, struct cm_id_private, id); +@@ -3477,7 +3546,14 @@ static int cm_migrate(struct ib_cm_id *c + (cm_id->lap_state == IB_CM_LAP_UNINIT || + cm_id->lap_state == IB_CM_LAP_IDLE)) { + cm_id->lap_state = IB_CM_LAP_IDLE; ++ /* Swap address vector */ ++ tmp_av = cm_id_priv->av; + cm_id_priv->av = cm_id_priv->alt_av; ++ cm_id_priv->alt_av = tmp_av; ++ /* Swap port send ready state */ ++ tmp_send_port_not_ready = cm_id_priv->prim_send_port_not_ready; ++ cm_id_priv->prim_send_port_not_ready = cm_id_priv->altr_send_port_not_ready; ++ cm_id_priv->altr_send_port_not_ready = tmp_send_port_not_ready; + } else + ret = -EINVAL; + spin_unlock_irqrestore(&cm_id_priv->lock, flags); +@@ -3888,6 +3964,9 @@ static void cm_add_one(struct ib_device + port->cm_dev = cm_dev; + port->port_num = i; + ++ INIT_LIST_HEAD(&port->cm_priv_prim_list); ++ INIT_LIST_HEAD(&port->cm_priv_altr_list); ++ + ret = cm_create_port_fs(port); + if (ret) + goto error1; +@@ -3945,6 +4024,8 @@ static void cm_remove_one(struct ib_devi + { + struct cm_device *cm_dev = client_data; + struct cm_port *port; ++ struct cm_id_private *cm_id_priv; ++ struct ib_mad_agent *cur_mad_agent; + struct ib_port_modify port_modify = { + .clr_port_cap_mask = IB_PORT_CM_SUP + }; +@@ -3968,15 +4049,27 @@ static void cm_remove_one(struct ib_devi + + port = cm_dev->port[i-1]; + ib_modify_port(ib_device, port->port_num, 0, &port_modify); ++ /* Mark all the cm_id's as not valid */ ++ spin_lock_irq(&cm.lock); ++ list_for_each_entry(cm_id_priv, &port->cm_priv_altr_list, altr_list) ++ cm_id_priv->altr_send_port_not_ready = 1; ++ list_for_each_entry(cm_id_priv, &port->cm_priv_prim_list, prim_list) ++ cm_id_priv->prim_send_port_not_ready = 1; ++ spin_unlock_irq(&cm.lock); + /* + * We flush the queue here after the going_down set, this + * verify that no new works will be queued in the recv handler, + * after that we can call the unregister_mad_agent + */ + flush_workqueue(cm.wq); +- ib_unregister_mad_agent(port->mad_agent); ++ spin_lock_irq(&cm.state_lock); ++ cur_mad_agent = port->mad_agent; ++ port->mad_agent = NULL; ++ spin_unlock_irq(&cm.state_lock); ++ ib_unregister_mad_agent(cur_mad_agent); + cm_remove_port_fs(port); + } ++ + device_unregister(cm_dev->device); + kfree(cm_dev); + } +@@ -3989,6 +4082,7 @@ static int __init ib_cm_init(void) + INIT_LIST_HEAD(&cm.device_list); + rwlock_init(&cm.device_lock); + spin_lock_init(&cm.lock); ++ spin_lock_init(&cm.state_lock); + cm.listen_service_table = RB_ROOT; + cm.listen_service_id = be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID); + cm.remote_id_table = RB_ROOT; diff --git a/queue-4.8/ib-core-avoid-unsigned-int-overflow-in-sg_alloc_table.patch b/queue-4.8/ib-core-avoid-unsigned-int-overflow-in-sg_alloc_table.patch new file mode 100644 index 00000000000..ab56bf7ec02 --- /dev/null +++ b/queue-4.8/ib-core-avoid-unsigned-int-overflow-in-sg_alloc_table.patch @@ -0,0 +1,35 @@ +From 3c7ba5760ab8eedec01159b267bb9bfcffe522ac Mon Sep 17 00:00:00 2001 +From: Mark Bloch +Date: Thu, 27 Oct 2016 16:36:31 +0300 +Subject: IB/core: Avoid unsigned int overflow in sg_alloc_table + +From: Mark Bloch + +commit 3c7ba5760ab8eedec01159b267bb9bfcffe522ac upstream. + +sg_alloc_table gets unsigned int as parameter while the driver +returns it as size_t. Check npages isn't greater than maximum +unsigned int. + +Fixes: eeb8461e36c9 ("IB: Refactor umem to use linear SG table") +Signed-off-by: Mark Bloch +Signed-off-by: Maor Gottlieb +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/umem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/core/umem.c ++++ b/drivers/infiniband/core/umem.c +@@ -174,7 +174,7 @@ struct ib_umem *ib_umem_get(struct ib_uc + + cur_base = addr & PAGE_MASK; + +- if (npages == 0) { ++ if (npages == 0 || npages > UINT_MAX) { + ret = -EINVAL; + goto out; + } diff --git a/queue-4.8/ib-hfi1-remove-incorrect-is_err-check.patch b/queue-4.8/ib-hfi1-remove-incorrect-is_err-check.patch new file mode 100644 index 00000000000..750bfe120a6 --- /dev/null +++ b/queue-4.8/ib-hfi1-remove-incorrect-is_err-check.patch @@ -0,0 +1,34 @@ +From 2b16056f845207967a32497f41cf92b57849f934 Mon Sep 17 00:00:00 2001 +From: Dennis Dalessandro +Date: Tue, 25 Oct 2016 13:12:46 -0700 +Subject: IB/hfi1: Remove incorrect IS_ERR check + +From: Dennis Dalessandro + +commit 2b16056f845207967a32497f41cf92b57849f934 upstream. + +Remove IS_ERR check from caching code as the function being called does +not actually return error pointers. + +Fixes: f19bd643dbde: "IB/hfi1: Prevent NULL pointer deferences in caching code" +Reported-by: Dan Carpenter +Reviewed-by: Dean Luick +Signed-off-by: Dennis Dalessandro +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/hfi1/user_sdma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/hfi1/user_sdma.c ++++ b/drivers/infiniband/hw/hfi1/user_sdma.c +@@ -1152,7 +1152,7 @@ static int pin_vector_pages(struct user_ + rb_node = hfi1_mmu_rb_extract(pq->handler, + (unsigned long)iovec->iov.iov_base, + iovec->iov.iov_len); +- if (rb_node && !IS_ERR(rb_node)) ++ if (rb_node) + node = container_of(rb_node, struct sdma_mmu_node, rb); + else + rb_node = NULL; diff --git a/queue-4.8/ib-mlx4-check-gid_index-return-value.patch b/queue-4.8/ib-mlx4-check-gid_index-return-value.patch new file mode 100644 index 00000000000..412e7a20d23 --- /dev/null +++ b/queue-4.8/ib-mlx4-check-gid_index-return-value.patch @@ -0,0 +1,37 @@ +From 37995116fecfce2b61ee3da6e73b3e394c6818f9 Mon Sep 17 00:00:00 2001 +From: Daniel Jurgens +Date: Thu, 10 Nov 2016 11:30:54 +0200 +Subject: IB/mlx4: Check gid_index return value + +From: Daniel Jurgens + +commit 37995116fecfce2b61ee3da6e73b3e394c6818f9 upstream. + +Check the returned GID index value and return an error if it is invalid. + +Fixes: 5070cd2239bd ('IB/mlx4: Replace mechanism for RoCE GID management') +Signed-off-by: Daniel Jurgens +Reviewed-by: Mark Bloch +Reviewed-by: Yuval Shaia +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/ah.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx4/ah.c ++++ b/drivers/infiniband/hw/mlx4/ah.c +@@ -102,7 +102,10 @@ static struct ib_ah *create_iboe_ah(stru + if (vlan_tag < 0x1000) + vlan_tag |= (ah_attr->sl & 7) << 13; + ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24)); +- ah->av.eth.gid_index = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index); ++ ret = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index); ++ if (ret < 0) ++ return ERR_PTR(ret); ++ ah->av.eth.gid_index = ret; + ah->av.eth.vlan = cpu_to_be16(vlan_tag); + ah->av.eth.hop_limit = ah_attr->grh.hop_limit; + if (ah_attr->static_rate) { diff --git a/queue-4.8/ib-mlx4-fix-create-cq-error-flow.patch b/queue-4.8/ib-mlx4-fix-create-cq-error-flow.patch new file mode 100644 index 00000000000..e65527a02cd --- /dev/null +++ b/queue-4.8/ib-mlx4-fix-create-cq-error-flow.patch @@ -0,0 +1,42 @@ +From 593ff73bcfdc79f79a8a0df55504f75ad3e5d1a9 Mon Sep 17 00:00:00 2001 +From: Matan Barak +Date: Thu, 10 Nov 2016 11:30:55 +0200 +Subject: IB/mlx4: Fix create CQ error flow + +From: Matan Barak + +commit 593ff73bcfdc79f79a8a0df55504f75ad3e5d1a9 upstream. + +Currently, if ib_copy_to_udata fails, the CQ +won't be deleted from the radix tree and the HW (HW2SW). + +Fixes: 225c7b1feef1 ('IB/mlx4: Add a driver Mellanox ConnectX InfiniBand adapters') +Signed-off-by: Matan Barak +Signed-off-by: Daniel Jurgens +Reviewed-by: Mark Bloch +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/cq.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx4/cq.c ++++ b/drivers/infiniband/hw/mlx4/cq.c +@@ -253,11 +253,14 @@ struct ib_cq *mlx4_ib_create_cq(struct i + if (context) + if (ib_copy_to_udata(udata, &cq->mcq.cqn, sizeof (__u32))) { + err = -EFAULT; +- goto err_dbmap; ++ goto err_cq_free; + } + + return &cq->ibcq; + ++err_cq_free: ++ mlx4_cq_free(dev->dev, &cq->mcq); ++ + err_dbmap: + if (context) + mlx4_ib_db_unmap_user(to_mucontext(context), &cq->db); diff --git a/queue-4.8/ib-mlx5-fix-fatal-error-dispatching.patch b/queue-4.8/ib-mlx5-fix-fatal-error-dispatching.patch new file mode 100644 index 00000000000..70df77b0ef2 --- /dev/null +++ b/queue-4.8/ib-mlx5-fix-fatal-error-dispatching.patch @@ -0,0 +1,54 @@ +From dbaaff2a2caa03d472b5cc53a3fbfd415c97dc26 Mon Sep 17 00:00:00 2001 +From: Eli Cohen +Date: Thu, 27 Oct 2016 16:36:44 +0300 +Subject: IB/mlx5: Fix fatal error dispatching + +From: Eli Cohen + +commit dbaaff2a2caa03d472b5cc53a3fbfd415c97dc26 upstream. + +When an internal error condition is detected, make sure to set the +device inactive after dispatching the event so ULPs can get a +notification of this event. + +Fixes: e126ba97dba9 ('mlx5: Add driver for Mellanox Connect-IB adapters') +Signed-off-by: Eli Cohen +Signed-off-by: Maor Gottlieb +Reviewed-by: Mohamad Haj Yahia +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/main.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -2100,14 +2100,14 @@ static void mlx5_ib_event(struct mlx5_co + { + struct mlx5_ib_dev *ibdev = (struct mlx5_ib_dev *)context; + struct ib_event ibev; +- ++ bool fatal = false; + u8 port = 0; + + switch (event) { + case MLX5_DEV_EVENT_SYS_ERROR: +- ibdev->ib_active = false; + ibev.event = IB_EVENT_DEVICE_FATAL; + mlx5_ib_handle_internal_error(ibdev); ++ fatal = true; + break; + + case MLX5_DEV_EVENT_PORT_UP: +@@ -2154,6 +2154,9 @@ static void mlx5_ib_event(struct mlx5_co + + if (ibdev->ib_active) + ib_dispatch_event(&ibev); ++ ++ if (fatal) ++ ibdev->ib_active = false; + } + + static void get_ext_port_caps(struct mlx5_ib_dev *dev) diff --git a/queue-4.8/ib-mlx5-fix-memory-leak-in-query-device.patch b/queue-4.8/ib-mlx5-fix-memory-leak-in-query-device.patch new file mode 100644 index 00000000000..d17bb68684b --- /dev/null +++ b/queue-4.8/ib-mlx5-fix-memory-leak-in-query-device.patch @@ -0,0 +1,44 @@ +From 90be7c8ab72853ff9fc407f01518a898df1f3045 Mon Sep 17 00:00:00 2001 +From: Majd Dibbiny +Date: Thu, 27 Oct 2016 16:36:39 +0300 +Subject: IB/mlx5: Fix memory leak in query device + +From: Majd Dibbiny + +commit 90be7c8ab72853ff9fc407f01518a898df1f3045 upstream. + +We need to free dev->port when we fail to enable RoCE or +initialize node data. + +Fixes: 0837e86a7a34 ('IB/mlx5: Add per port counters') +Signed-off-by: Majd Dibbiny +Signed-off-by: Maor Gottlieb +Reviewed-by: Mark Bloch +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -2835,7 +2835,7 @@ static void *mlx5_ib_add(struct mlx5_cor + } + err = init_node_data(dev); + if (err) +- goto err_dealloc; ++ goto err_free_port; + + mutex_init(&dev->flow_db.lock); + mutex_init(&dev->cap_mask_mutex); +@@ -2845,7 +2845,7 @@ static void *mlx5_ib_add(struct mlx5_cor + if (ll == IB_LINK_LAYER_ETHERNET) { + err = mlx5_enable_roce(dev); + if (err) +- goto err_dealloc; ++ goto err_free_port; + } + + err = create_dev_resources(&dev->devr); diff --git a/queue-4.8/ib-mlx5-fix-null-pointer-dereference-on-debug-print.patch b/queue-4.8/ib-mlx5-fix-null-pointer-dereference-on-debug-print.patch new file mode 100644 index 00000000000..49e211b44dc --- /dev/null +++ b/queue-4.8/ib-mlx5-fix-null-pointer-dereference-on-debug-print.patch @@ -0,0 +1,36 @@ +From a1ab8402d15d2305d2315d96ec3294bfdf16587e Mon Sep 17 00:00:00 2001 +From: Eli Cohen +Date: Thu, 27 Oct 2016 16:36:46 +0300 +Subject: IB/mlx5: Fix NULL pointer dereference on debug print + +From: Eli Cohen + +commit a1ab8402d15d2305d2315d96ec3294bfdf16587e upstream. + +For XRC QP CQs may not exist. Check before attempting dereference. + +Fixes: e126ba97dba9 ('mlx5: Add driver for Mellanox Connect-IB adapters') +Signed-off-by: Eli Cohen +Signed-off-by: Maor Gottlieb +Reviewed-by: Yishai Hadas +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/qp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -2037,8 +2037,8 @@ struct ib_qp *mlx5_ib_create_qp(struct i + + mlx5_ib_dbg(dev, "ib qpnum 0x%x, mlx qpn 0x%x, rcqn 0x%x, scqn 0x%x\n", + qp->ibqp.qp_num, qp->trans_qp.base.mqp.qpn, +- to_mcq(init_attr->recv_cq)->mcq.cqn, +- to_mcq(init_attr->send_cq)->mcq.cqn); ++ init_attr->recv_cq ? to_mcq(init_attr->recv_cq)->mcq.cqn : -1, ++ init_attr->send_cq ? to_mcq(init_attr->send_cq)->mcq.cqn : -1); + + qp->trans_qp.xrcdn = xrcdn; + diff --git a/queue-4.8/ib-mlx5-use-cache-line-size-to-select-cqe-stride.patch b/queue-4.8/ib-mlx5-use-cache-line-size-to-select-cqe-stride.patch new file mode 100644 index 00000000000..463519ac06d --- /dev/null +++ b/queue-4.8/ib-mlx5-use-cache-line-size-to-select-cqe-stride.patch @@ -0,0 +1,41 @@ +From 16b0e0695a73b68d8ca40288c8f9614ef208917b Mon Sep 17 00:00:00 2001 +From: Daniel Jurgens +Date: Thu, 27 Oct 2016 16:36:41 +0300 +Subject: IB/mlx5: Use cache line size to select CQE stride + +From: Daniel Jurgens + +commit 16b0e0695a73b68d8ca40288c8f9614ef208917b upstream. + +When creating kernel CQs use 128B CQE stride if the +cache line size is 128B, 64B otherwise. This prevents +multiple CQEs from residing in a 128B cache line, +which can cause retries when there are concurrent +read and writes in one cache line. + +Tested with IPoIB on PPC64, saw ~5% throughput +improvement. + +Fixes: e126ba97dba9 ('mlx5: Add driver for Mellanox Connect-IB adapters') +Signed-off-by: Daniel Jurgens +Signed-off-by: Maor Gottlieb +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/cq.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/mlx5/cq.c ++++ b/drivers/infiniband/hw/mlx5/cq.c +@@ -917,8 +917,7 @@ struct ib_cq *mlx5_ib_create_cq(struct i + if (err) + goto err_create; + } else { +- /* for now choose 64 bytes till we have a proper interface */ +- cqe_size = 64; ++ cqe_size = cache_line_size() == 128 ? 128 : 64; + err = create_cq_kernel(dev, cq, entries, cqe_size, &cqb, + &index, &inlen); + if (err) diff --git a/queue-4.8/ib-mlx5-validate-requested-rqt-size.patch b/queue-4.8/ib-mlx5-validate-requested-rqt-size.patch new file mode 100644 index 00000000000..ec2a4a6c6c6 --- /dev/null +++ b/queue-4.8/ib-mlx5-validate-requested-rqt-size.patch @@ -0,0 +1,39 @@ +From efd7f40082a0dfd112eb87ff2124467a5739216f Mon Sep 17 00:00:00 2001 +From: Maor Gottlieb +Date: Thu, 27 Oct 2016 16:36:40 +0300 +Subject: IB/mlx5: Validate requested RQT size + +From: Maor Gottlieb + +commit efd7f40082a0dfd112eb87ff2124467a5739216f upstream. + +Validate that the requested size of RQT is supported by firmware. + +Fixes: c5f9092936fe ('IB/mlx5: Add Receive Work Queue Indirection table operations') +Signed-off-by: Maor Gottlieb +Reviewed-by: Yishai Hadas +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/qp.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -4702,6 +4702,14 @@ struct ib_rwq_ind_table *mlx5_ib_create_ + udata->inlen)) + return ERR_PTR(-EOPNOTSUPP); + ++ if (init_attr->log_ind_tbl_size > ++ MLX5_CAP_GEN(dev->mdev, log_max_rqt_size)) { ++ mlx5_ib_dbg(dev, "log_ind_tbl_size = %d is bigger than supported = %d\n", ++ init_attr->log_ind_tbl_size, ++ MLX5_CAP_GEN(dev->mdev, log_max_rqt_size)); ++ return ERR_PTR(-EINVAL); ++ } ++ + min_resp_len = offsetof(typeof(resp), reserved) + sizeof(resp.reserved); + if (udata->outlen && udata->outlen < min_resp_len) + return ERR_PTR(-EINVAL); diff --git a/queue-4.8/ib-rxe-clear-queue-buffer-when-modifying-qp-to-reset.patch b/queue-4.8/ib-rxe-clear-queue-buffer-when-modifying-qp-to-reset.patch new file mode 100644 index 00000000000..d9b93e43381 --- /dev/null +++ b/queue-4.8/ib-rxe-clear-queue-buffer-when-modifying-qp-to-reset.patch @@ -0,0 +1,68 @@ +From aa75b07b478a774b1432e2df1be5cd8ae834de0f Mon Sep 17 00:00:00 2001 +From: Yonatan Cohen +Date: Wed, 16 Nov 2016 10:39:17 +0200 +Subject: IB/rxe: Clear queue buffer when modifying QP to reset + +From: Yonatan Cohen + +commit aa75b07b478a774b1432e2df1be5cd8ae834de0f upstream. + +RXE resets the send-q only once in rxe_qp_init_req() when +QP is created, but when the QP is reused after QP reset, the send-q +holds previous garbage data. + +This garbage data wrongly fails CQEs that otherwise +should have completed successfully. + +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Signed-off-by: Yonatan Cohen +Reviewed-by: Moni Shoua +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/sw/rxe/rxe_qp.c | 1 + + drivers/infiniband/sw/rxe/rxe_queue.c | 9 +++++++++ + drivers/infiniband/sw/rxe/rxe_queue.h | 2 ++ + 3 files changed, 12 insertions(+) + +--- a/drivers/infiniband/sw/rxe/rxe_qp.c ++++ b/drivers/infiniband/sw/rxe/rxe_qp.c +@@ -522,6 +522,7 @@ static void rxe_qp_reset(struct rxe_qp * + if (qp->sq.queue) { + __rxe_do_task(&qp->comp.task); + __rxe_do_task(&qp->req.task); ++ rxe_queue_reset(qp->sq.queue); + } + + /* cleanup attributes */ +--- a/drivers/infiniband/sw/rxe/rxe_queue.c ++++ b/drivers/infiniband/sw/rxe/rxe_queue.c +@@ -84,6 +84,15 @@ err1: + return -EINVAL; + } + ++inline void rxe_queue_reset(struct rxe_queue *q) ++{ ++ /* queue is comprised from header and the memory ++ * of the actual queue. See "struct rxe_queue_buf" in rxe_queue.h ++ * reset only the queue itself and not the management header ++ */ ++ memset(q->buf->data, 0, q->buf_size - sizeof(struct rxe_queue_buf)); ++} ++ + struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe, + int *num_elem, + unsigned int elem_size) +--- a/drivers/infiniband/sw/rxe/rxe_queue.h ++++ b/drivers/infiniband/sw/rxe/rxe_queue.h +@@ -84,6 +84,8 @@ int do_mmap_info(struct rxe_dev *rxe, + size_t buf_size, + struct rxe_mmap_info **ip_p); + ++void rxe_queue_reset(struct rxe_queue *q); ++ + struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe, + int *num_elem, + unsigned int elem_size); diff --git a/queue-4.8/ib-rxe-fix-handling-of-erroneous-wr.patch b/queue-4.8/ib-rxe-fix-handling-of-erroneous-wr.patch new file mode 100644 index 00000000000..5548eb024b1 --- /dev/null +++ b/queue-4.8/ib-rxe-fix-handling-of-erroneous-wr.patch @@ -0,0 +1,99 @@ +From 002e062e13db10973adb8302f231e48b477c7ccf Mon Sep 17 00:00:00 2001 +From: Yonatan Cohen +Date: Wed, 16 Nov 2016 10:39:15 +0200 +Subject: IB/rxe: Fix handling of erroneous WR + +From: Yonatan Cohen + +commit 002e062e13db10973adb8302f231e48b477c7ccf upstream. + +To correctly handle a erroneous WR this fix does the following +1. Make sure the bad WQE causes a user completion event. +2. Call rxe_completer to handle the erred WQE. + +Before the fix, when rxe_requester found a bad WQE, it changed its +status to IB_WC_LOC_PROT_ERR and exit with 0 for non RC QPs. + +If this was the 1st WQE then there would be no ACK to invoke the +completer and this bad WQE would be stuck in the QP's send-q. + +On top of that the requester exiting with 0 caused rxe_do_task to +endlessly invoke rxe_requester, resulting in a soft-lockup attached +below. + +In case the WQE was not the 1st and rxe_completer did get a chance to +handle the bad WQE, it did not cause a complete event since the WQE's +IB_SEND_SIGNALED flag was not set. + +Setting WQE status to IB_SEND_SIGNALED is subject to IBA spec +version 1.2.1, section 10.7.3.1 Signaled Completions. + +NMI watchdog: BUG: soft lockup - CPU#7 stuck for 22s! +[] ? rxe_pool_get_index+0x35/0xb0 [rdma_rxe] +[] lookup_mem+0x3c/0xc0 [rdma_rxe] +[] copy_data+0x1c4/0x230 [rdma_rxe] +[] rxe_requester+0x9d0/0x1100 [rdma_rxe] +[] ? kfree_skbmem+0x5a/0x60 +[] rxe_do_task+0x89/0xf0 [rdma_rxe] +[] rxe_run_task+0x12/0x30 [rdma_rxe] +[] rxe_post_send+0x41a/0x550 [rdma_rxe] +[] ? __kmalloc+0x182/0x200 +[] ? down_read+0x12/0x40 +[] ib_uverbs_post_send+0x532/0x540 [ib_uverbs] +[] ? tcp_sendmsg+0x402/0xb80 +[] ib_uverbs_write+0x18c/0x3f0 [ib_uverbs] +[] ? inet_recvmsg+0x7e/0xb0 +[] ? sock_recvmsg+0x3d/0x50 +[] __vfs_write+0x37/0x140 +[] vfs_write+0xb2/0x1b0 +[] SyS_write+0x55/0xc0 +[] entry_SYSCALL_64_fastpath+0x1a/0xa + +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Signed-off-by: Yonatan Cohen +Reviewed-by: Moni Shoua +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/sw/rxe/rxe_req.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +--- a/drivers/infiniband/sw/rxe/rxe_req.c ++++ b/drivers/infiniband/sw/rxe/rxe_req.c +@@ -695,7 +695,8 @@ next_wqe: + qp->req.wqe_index); + wqe->state = wqe_state_done; + wqe->status = IB_WC_SUCCESS; +- goto complete; ++ __rxe_do_task(&qp->comp.task); ++ return 0; + } + payload = mtu; + } +@@ -744,13 +745,17 @@ err: + wqe->status = IB_WC_LOC_PROT_ERR; + wqe->state = wqe_state_error; + +-complete: +- if (qp_type(qp) != IB_QPT_RC) { +- while (rxe_completer(qp) == 0) +- ; +- } +- +- return 0; ++ /* ++ * IBA Spec. Section 10.7.3.1 SIGNALED COMPLETIONS ++ * ---------8<---------8<------------- ++ * ...Note that if a completion error occurs, a Work Completion ++ * will always be generated, even if the signaling ++ * indicator requests an Unsignaled Completion. ++ * ---------8<---------8<------------- ++ */ ++ wqe->wr.send_flags |= IB_SEND_SIGNALED; ++ __rxe_do_task(&qp->comp.task); ++ return -EAGAIN; + + exit: + return -EAGAIN; diff --git a/queue-4.8/ib-rxe-fix-kernel-panic-in-udp-tunnel-with-gro-and-rx-checksum.patch b/queue-4.8/ib-rxe-fix-kernel-panic-in-udp-tunnel-with-gro-and-rx-checksum.patch new file mode 100644 index 00000000000..2f24a43fd75 --- /dev/null +++ b/queue-4.8/ib-rxe-fix-kernel-panic-in-udp-tunnel-with-gro-and-rx-checksum.patch @@ -0,0 +1,108 @@ +From 1454ca3a97e147bb91e98b087446c39cf6692a48 Mon Sep 17 00:00:00 2001 +From: Yonatan Cohen +Date: Wed, 16 Nov 2016 10:39:14 +0200 +Subject: IB/rxe: Fix kernel panic in UDP tunnel with GRO and RX checksum + +From: Yonatan Cohen + +commit 1454ca3a97e147bb91e98b087446c39cf6692a48 upstream. + +Missing initialization of udp_tunnel_sock_cfg causes to following +kernel panic, while kernel tries to execute gro_receive(). + +While being there, we converted udp_port_cfg to use the same +initialization scheme as udp_tunnel_sock_cfg. + +------------[ cut here ]------------ +kernel tried to execute NX-protected page - exploit attempt? (uid: 0) +BUG: unable to handle kernel paging request at ffffffffa0588c50 +IP: [] __this_module+0x50/0xffffffffffff8400 [ib_rxe] +PGD 1c09067 PUD 1c0a063 PMD bb394067 PTE 80000000ad5e8163 +Oops: 0011 [#1] SMP +Modules linked in: ib_rxe ip6_udp_tunnel udp_tunnel +CPU: 5 PID: 0 Comm: swapper/5 Not tainted 4.7.0-rc3+ #2 +Hardware name: Red Hat KVM, BIOS Bochs 01/01/2011 +task: ffff880235e4e680 ti: ffff880235e68000 task.ti: ffff880235e68000 +RIP: 0010:[] +[] __this_module+0x50/0xffffffffffff8400 [ib_rxe] +RSP: 0018:ffff880237343c80 EFLAGS: 00010282 +RAX: 00000000dffe482d RBX: ffff8800ae330900 RCX: 000000002001b712 +RDX: ffff8800ae330900 RSI: ffff8800ae102578 RDI: ffff880235589c00 +RBP: ffff880237343cb0 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: ffff8800ae33e262 +R13: ffff880235589c00 R14: 0000000000000014 R15: ffff8800ae102578 +FS: 0000000000000000(0000) GS:ffff880237340000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: ffffffffa0588c50 CR3: 0000000001c06000 CR4: 00000000000006e0 +Stack: +ffffffff8160860e ffff8800ae330900 ffff8800ae102578 0000000000000014 +000000000000004e ffff8800ae102578 ffff880237343ce0 ffffffff816088fb +0000000000000000 ffff8800ae330900 0000000000000000 00000000ffad0000 +Call Trace: + +[] ? udp_gro_receive+0xde/0x130 +[] udp4_gro_receive+0x10b/0x2d0 +[] inet_gro_receive+0x1d3/0x270 +[] dev_gro_receive+0x269/0x3b0 +[] napi_gro_receive+0x38/0x120 +[] mlx5e_handle_rx_cqe+0x27e/0x340 [mlx5_core] +[] mlx5e_poll_rx_cq+0x66/0x6d0 [mlx5_core] +[] mlx5e_napi_poll+0x8e/0x400 [mlx5_core] +[] net_rx_action+0x160/0x380 +[] __do_softirq+0xd7/0x2c5 +[] irq_exit+0xf5/0x100 +[] do_IRQ+0x56/0xd0 +[] common_interrupt+0x8c/0x8c + +[] ? native_safe_halt+0x6/0x10 +[] default_idle+0x1e/0xd0 +[] arch_cpu_idle+0xf/0x20 +[] default_idle_call+0x3c/0x50 +[] cpu_startup_entry+0x323/0x3c0 +[] start_secondary+0x15c/0x1a0 +RIP [] __this_module+0x50/0xffffffffffff8400 [ib_rxe] +RSP +CR2: ffffffffa0588c50 +---[ end trace 489ee31fa7614ac5 ]--- +Kernel panic - not syncing: Fatal exception in interrupt +Kernel Offset: disabled +---[ end Kernel panic - not syncing: Fatal exception in interrupt +------------[ cut here ]------------ + +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Signed-off-by: Yonatan Cohen +Reviewed-by: Moni Shoua +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/sw/rxe/rxe_net.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/infiniband/sw/rxe/rxe_net.c ++++ b/drivers/infiniband/sw/rxe/rxe_net.c +@@ -243,10 +243,8 @@ static struct socket *rxe_setup_udp_tunn + { + int err; + struct socket *sock; +- struct udp_port_cfg udp_cfg; +- struct udp_tunnel_sock_cfg tnl_cfg; +- +- memset(&udp_cfg, 0, sizeof(udp_cfg)); ++ struct udp_port_cfg udp_cfg = {0}; ++ struct udp_tunnel_sock_cfg tnl_cfg = {0}; + + if (ipv6) { + udp_cfg.family = AF_INET6; +@@ -264,10 +262,8 @@ static struct socket *rxe_setup_udp_tunn + return ERR_PTR(err); + } + +- tnl_cfg.sk_user_data = NULL; + tnl_cfg.encap_type = 1; + tnl_cfg.encap_rcv = rxe_udp_encap_recv; +- tnl_cfg.encap_destroy = NULL; + + /* Setup UDP tunnel */ + setup_udp_tunnel_sock(net, sock, &tnl_cfg); diff --git a/queue-4.8/ib-rxe-update-qp-state-for-user-query.patch b/queue-4.8/ib-rxe-update-qp-state-for-user-query.patch new file mode 100644 index 00000000000..33a15796b2a --- /dev/null +++ b/queue-4.8/ib-rxe-update-qp-state-for-user-query.patch @@ -0,0 +1,36 @@ +From 6d931308f55faaef3f30bd0346c47f99528b229d Mon Sep 17 00:00:00 2001 +From: Yonatan Cohen +Date: Wed, 16 Nov 2016 10:39:18 +0200 +Subject: IB/rxe: Update qp state for user query + +From: Yonatan Cohen + +commit 6d931308f55faaef3f30bd0346c47f99528b229d upstream. + +The method rxe_qp_error() transitions QP to error state +and make sure the QP is drained. It did not though update +the QP state for user's query. + +This patch fixes this. + +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Signed-off-by: Yonatan Cohen +Reviewed-by: Moni Shoua +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/sw/rxe/rxe_qp.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/infiniband/sw/rxe/rxe_qp.c ++++ b/drivers/infiniband/sw/rxe/rxe_qp.c +@@ -573,6 +573,7 @@ void rxe_qp_error(struct rxe_qp *qp) + { + qp->req.state = QP_STATE_ERROR; + qp->resp.state = QP_STATE_ERROR; ++ qp->attr.qp_state = IB_QPS_ERR; + + /* drain work and packet queues */ + rxe_run_task(&qp->resp.task, 1); diff --git a/queue-4.8/ib-uverbs-fix-leak-of-xrc-target-qps.patch b/queue-4.8/ib-uverbs-fix-leak-of-xrc-target-qps.patch new file mode 100644 index 00000000000..f3b3a31de4a --- /dev/null +++ b/queue-4.8/ib-uverbs-fix-leak-of-xrc-target-qps.patch @@ -0,0 +1,42 @@ +From 5b810a242c28e1d8d64d718cebe75b79d86a0b2d Mon Sep 17 00:00:00 2001 +From: Tariq Toukan +Date: Thu, 27 Oct 2016 16:36:26 +0300 +Subject: IB/uverbs: Fix leak of XRC target QPs + +From: Tariq Toukan + +commit 5b810a242c28e1d8d64d718cebe75b79d86a0b2d upstream. + +The real QP is destroyed in case of the ref count reaches zero, but +for XRC target QPs this call was missed and caused to QP leaks. + +Let's call to destroy for all flows. + +Fixes: 0e0ec7e0638e ('RDMA/core: Export ib_open_qp() to share XRC...') +Signed-off-by: Tariq Toukan +Signed-off-by: Noa Osherovich +Signed-off-by: Leon Romanovsky +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs_main.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +--- a/drivers/infiniband/core/uverbs_main.c ++++ b/drivers/infiniband/core/uverbs_main.c +@@ -262,12 +262,9 @@ static int ib_uverbs_cleanup_ucontext(st + container_of(uobj, struct ib_uqp_object, uevent.uobject); + + idr_remove_uobj(&ib_uverbs_qp_idr, uobj); +- if (qp != qp->real_qp) { +- ib_close_qp(qp); +- } else { ++ if (qp == qp->real_qp) + ib_uverbs_detach_umcast(qp, uqp); +- ib_destroy_qp(qp); +- } ++ ib_destroy_qp(qp); + ib_uverbs_release_uevent(file, &uqp->uevent); + kfree(uqp); + } diff --git a/queue-4.8/iwlwifi-mvm-fix-d3_test-with-unified-d0-d3-images.patch b/queue-4.8/iwlwifi-mvm-fix-d3_test-with-unified-d0-d3-images.patch new file mode 100644 index 00000000000..887eed60d4f --- /dev/null +++ b/queue-4.8/iwlwifi-mvm-fix-d3_test-with-unified-d0-d3-images.patch @@ -0,0 +1,64 @@ +From 85cd69b8f1f7e289fe931a82889e673fd0f04842 Mon Sep 17 00:00:00 2001 +From: Luca Coelho +Date: Wed, 5 Oct 2016 11:24:12 +0300 +Subject: iwlwifi: mvm: fix d3_test with unified D0/D3 images + +From: Luca Coelho + +commit 85cd69b8f1f7e289fe931a82889e673fd0f04842 upstream. + +When a unified D0/D3 image is used, we don't restart the FW in the +D0->D3->D0 transitions. Therefore, the d3_test functionality should +not call ieee8021_restart_hw() when the resuming either. + +Fixes: commit 23ae61282b88 ("iwlwifi: mvm: Do not switch to D3 image on suspend") +Signed-off-by: Luca Coelho +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +@@ -2290,7 +2290,8 @@ static void iwl_mvm_d3_test_disconn_work + static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file) + { + struct iwl_mvm *mvm = inode->i_private; +- int remaining_time = 10; ++ bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, ++ IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); + + mvm->d3_test_active = false; + +@@ -2301,17 +2302,21 @@ static int iwl_mvm_d3_test_release(struc + mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; + + iwl_abort_notification_waits(&mvm->notif_wait); +- ieee80211_restart_hw(mvm->hw); ++ if (!unified_image) { ++ int remaining_time = 10; + +- /* wait for restart and disconnect all interfaces */ +- while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && +- remaining_time > 0) { +- remaining_time--; +- msleep(1000); +- } ++ ieee80211_restart_hw(mvm->hw); ++ ++ /* wait for restart and disconnect all interfaces */ ++ while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && ++ remaining_time > 0) { ++ remaining_time--; ++ msleep(1000); ++ } + +- if (remaining_time == 0) +- IWL_ERR(mvm, "Timed out waiting for HW restart to finish!\n"); ++ if (remaining_time == 0) ++ IWL_ERR(mvm, "Timed out waiting for HW restart!\n"); ++ } + + ieee80211_iterate_active_interfaces_atomic( + mvm->hw, IEEE80211_IFACE_ITER_NORMAL, diff --git a/queue-4.8/iwlwifi-mvm-fix-netdetect-starting-stopping-for-unified-images.patch b/queue-4.8/iwlwifi-mvm-fix-netdetect-starting-stopping-for-unified-images.patch new file mode 100644 index 00000000000..8c6f5dd026c --- /dev/null +++ b/queue-4.8/iwlwifi-mvm-fix-netdetect-starting-stopping-for-unified-images.patch @@ -0,0 +1,107 @@ +From 5a143db8c4a28dab6423cb6197e9f1389da375f2 Mon Sep 17 00:00:00 2001 +From: Luca Coelho +Date: Wed, 5 Oct 2016 09:28:53 +0300 +Subject: iwlwifi: mvm: fix netdetect starting/stopping for unified images + +From: Luca Coelho + +commit 5a143db8c4a28dab6423cb6197e9f1389da375f2 upstream. + +With unified images, we need to make sure the net-detect scan is +stopped after resuming, since we don't restart the FW. Also, we need +to make sure we check if there are enough scan slots available to run +it, as we do with other scans. + +Fixes: commit 23ae61282b88 ("iwlwifi: mvm: Do not switch to D3 image on suspend") +Signed-off-by: Luca Coelho +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 19 ++++++++++++++ + drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 33 +++++++++++++++++++++----- + 2 files changed, 46 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +@@ -1087,6 +1087,15 @@ iwl_mvm_netdetect_config(struct iwl_mvm + ret = iwl_mvm_switch_to_d3(mvm); + if (ret) + return ret; ++ } else { ++ /* In theory, we wouldn't have to stop a running sched ++ * scan in order to start another one (for ++ * net-detect). But in practice this doesn't seem to ++ * work properly, so stop any running sched_scan now. ++ */ ++ ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true); ++ if (ret) ++ return ret; + } + + /* rfkill release can be either for wowlan or netdetect */ +@@ -2088,6 +2097,16 @@ static int __iwl_mvm_resume(struct iwl_m + iwl_mvm_update_changed_regdom(mvm); + + if (mvm->net_detect) { ++ /* If this is a non-unified image, we restart the FW, ++ * so no need to stop the netdetect scan. If that ++ * fails, continue and try to get the wake-up reasons, ++ * but trigger a HW restart by keeping a failure code ++ * in ret. ++ */ ++ if (unified_image) ++ ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_NETDETECT, ++ false); ++ + iwl_mvm_query_netdetect_reasons(mvm, vif); + /* has unlocked the mutex, so skip that */ + goto out; +--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +@@ -1185,6 +1185,9 @@ static int iwl_mvm_num_scans(struct iwl_ + + static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type) + { ++ bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, ++ IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG); ++ + /* This looks a bit arbitrary, but the idea is that if we run + * out of possible simultaneous scans and the userspace is + * trying to run a scan type that is already running, we +@@ -1211,12 +1214,30 @@ static int iwl_mvm_check_running_scans(s + return -EBUSY; + return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true); + case IWL_MVM_SCAN_NETDETECT: +- /* No need to stop anything for net-detect since the +- * firmware is restarted anyway. This way, any sched +- * scans that were running will be restarted when we +- * resume. +- */ +- return 0; ++ /* For non-unified images, there's no need to stop ++ * anything for net-detect since the firmware is ++ * restarted anyway. This way, any sched scans that ++ * were running will be restarted when we resume. ++ */ ++ if (!unified_image) ++ return 0; ++ ++ /* If this is a unified image and we ran out of scans, ++ * we need to stop something. Prefer stopping regular ++ * scans, because the results are useless at this ++ * point, and we should be able to keep running ++ * another scheduled scan while suspended. ++ */ ++ if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK) ++ return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, ++ true); ++ if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK) ++ return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, ++ true); ++ ++ /* fall through, something is wrong if no scan was ++ * running but we ran out of scans. ++ */ + default: + WARN_ON(1); + break; diff --git a/queue-4.8/iwlwifi-mvm-wake-the-wait-queue-when-the-rx-sync-counter-is-zero.patch b/queue-4.8/iwlwifi-mvm-wake-the-wait-queue-when-the-rx-sync-counter-is-zero.patch new file mode 100644 index 00000000000..61b9d704b81 --- /dev/null +++ b/queue-4.8/iwlwifi-mvm-wake-the-wait-queue-when-the-rx-sync-counter-is-zero.patch @@ -0,0 +1,81 @@ +From 3a732c65de427fdae67a243fd331356034b5a1e8 Mon Sep 17 00:00:00 2001 +From: Sara Sharon +Date: Sun, 9 Oct 2016 17:34:24 +0300 +Subject: iwlwifi: mvm: wake the wait queue when the RX sync counter is zero + +From: Sara Sharon + +commit 3a732c65de427fdae67a243fd331356034b5a1e8 upstream. + +When we sync the RX queues the driver waits to receive echo +notification on all the RX queues. +The wait queue is set with timeout until all queues have received +the notification. +However, iwl_mvm_rx_queue_notif() never woke up the wait queue, +with the result of the counter value being checked only when the +timeout expired. +This may cause a latency of up to 1 second. + +Fixes: 0636b938214c ("iwlwifi: mvm: implement driver RX queues sync command") +Signed-off-by: Sara Sharon +Signed-off-by: Luca Coelho +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +-- + drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 1 + + drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 1 + + drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 3 ++- + 4 files changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +@@ -4097,7 +4097,6 @@ void iwl_mvm_sync_rx_queues_internal(str + struct iwl_mvm_internal_rxq_notif *notif, + u32 size) + { +- DECLARE_WAIT_QUEUE_HEAD_ONSTACK(notif_waitq); + u32 qmask = BIT(mvm->trans->num_rx_queues) - 1; + int ret; + +@@ -4119,7 +4118,7 @@ void iwl_mvm_sync_rx_queues_internal(str + } + + if (notif->sync) +- ret = wait_event_timeout(notif_waitq, ++ ret = wait_event_timeout(mvm->rx_sync_waitq, + atomic_read(&mvm->queue_sync_counter) == 0, + HZ); + WARN_ON_ONCE(!ret); +--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +@@ -932,6 +932,7 @@ struct iwl_mvm { + /* sync d0i3_tx queue and IWL_MVM_STATUS_IN_D0I3 status flag */ + spinlock_t d0i3_tx_lock; + wait_queue_head_t d0i3_exit_waitq; ++ wait_queue_head_t rx_sync_waitq; + + /* BT-Coex */ + struct iwl_bt_coex_profile_notif last_bt_notif; +--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +@@ -618,6 +618,7 @@ iwl_op_mode_mvm_start(struct iwl_trans * + spin_lock_init(&mvm->refs_lock); + skb_queue_head_init(&mvm->d0i3_tx); + init_waitqueue_head(&mvm->d0i3_exit_waitq); ++ init_waitqueue_head(&mvm->rx_sync_waitq); + + atomic_set(&mvm->queue_sync_counter, 0); + +--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +@@ -545,7 +545,8 @@ void iwl_mvm_rx_queue_notif(struct iwl_m + "Received expired RX queue sync message\n"); + return; + } +- atomic_dec(&mvm->queue_sync_counter); ++ if (!atomic_dec_return(&mvm->queue_sync_counter)) ++ wake_up(&mvm->rx_sync_waitq); + } + + switch (internal_notif->type) { diff --git a/queue-4.8/iwlwifi-pcie-fix-splc-structure-parsing.patch b/queue-4.8/iwlwifi-pcie-fix-splc-structure-parsing.patch new file mode 100644 index 00000000000..9f261446565 --- /dev/null +++ b/queue-4.8/iwlwifi-pcie-fix-splc-structure-parsing.patch @@ -0,0 +1,153 @@ +From e0d9727c111a5917a1184c71c1a8e6f78c7fc41d Mon Sep 17 00:00:00 2001 +From: Luca Coelho +Date: Thu, 13 Oct 2016 10:07:07 +0300 +Subject: iwlwifi: pcie: fix SPLC structure parsing + +From: Luca Coelho + +commit e0d9727c111a5917a1184c71c1a8e6f78c7fc41d upstream. + +The SPLC data parsing is too restrictive and was not trying find the +correct element for WiFi. This causes problems with some BIOSes where +the SPLC method exists, but doesn't have a WiFi entry on the first +element of the list. The domain type values are also incorrect +according to the specification. + +Fix this by complying with the actual specification. + +Additionally, replace all occurrences of SPLX to SPLC, since SPLX is +only a structure internal to the ACPI tables, and may not even exist. + +Fixes: bcb079a14d75 ("iwlwifi: pcie: retrieve and parse ACPI power limitations") +Reported-by: Chris Rorvick +Tested-by: Paul Bolle +Tested-by: Chris Rorvick +Signed-off-by: Luca Coelho +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 77 +++++++++++++++----------- + 1 file changed, 47 insertions(+), 30 deletions(-) + +--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +@@ -526,48 +526,64 @@ static const struct pci_device_id iwl_hw + MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); + + #ifdef CONFIG_ACPI +-#define SPL_METHOD "SPLC" +-#define SPL_DOMAINTYPE_MODULE BIT(0) +-#define SPL_DOMAINTYPE_WIFI BIT(1) +-#define SPL_DOMAINTYPE_WIGIG BIT(2) +-#define SPL_DOMAINTYPE_RFEM BIT(3) ++#define ACPI_SPLC_METHOD "SPLC" ++#define ACPI_SPLC_DOMAIN_WIFI (0x07) + +-static u64 splx_get_pwr_limit(struct iwl_trans *trans, union acpi_object *splx) ++static u64 splc_get_pwr_limit(struct iwl_trans *trans, union acpi_object *splc) + { +- union acpi_object *limits, *domain_type, *power_limit; ++ union acpi_object *data_pkg, *dflt_pwr_limit; ++ int i; + +- if (splx->type != ACPI_TYPE_PACKAGE || +- splx->package.count != 2 || +- splx->package.elements[0].type != ACPI_TYPE_INTEGER || +- splx->package.elements[0].integer.value != 0) { +- IWL_ERR(trans, "Unsupported splx structure\n"); ++ /* We need at least two elements, one for the revision and one ++ * for the data itself. Also check that the revision is ++ * supported (currently only revision 0). ++ */ ++ if (splc->type != ACPI_TYPE_PACKAGE || ++ splc->package.count < 2 || ++ splc->package.elements[0].type != ACPI_TYPE_INTEGER || ++ splc->package.elements[0].integer.value != 0) { ++ IWL_DEBUG_INFO(trans, ++ "Unsupported structure returned by the SPLC method. Ignoring.\n"); + return 0; + } + +- limits = &splx->package.elements[1]; +- if (limits->type != ACPI_TYPE_PACKAGE || +- limits->package.count < 2 || +- limits->package.elements[0].type != ACPI_TYPE_INTEGER || +- limits->package.elements[1].type != ACPI_TYPE_INTEGER) { +- IWL_ERR(trans, "Invalid limits element\n"); +- return 0; ++ /* loop through all the packages to find the one for WiFi */ ++ for (i = 1; i < splc->package.count; i++) { ++ union acpi_object *domain; ++ ++ data_pkg = &splc->package.elements[i]; ++ ++ /* Skip anything that is not a package with the right ++ * amount of elements (i.e. at least 2 integers). ++ */ ++ if (data_pkg->type != ACPI_TYPE_PACKAGE || ++ data_pkg->package.count < 2 || ++ data_pkg->package.elements[0].type != ACPI_TYPE_INTEGER || ++ data_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) ++ continue; ++ ++ domain = &data_pkg->package.elements[0]; ++ if (domain->integer.value == ACPI_SPLC_DOMAIN_WIFI) ++ break; ++ ++ data_pkg = NULL; + } + +- domain_type = &limits->package.elements[0]; +- power_limit = &limits->package.elements[1]; +- if (!(domain_type->integer.value & SPL_DOMAINTYPE_WIFI)) { +- IWL_DEBUG_INFO(trans, "WiFi power is not limited\n"); ++ if (!data_pkg) { ++ IWL_DEBUG_INFO(trans, ++ "No element for the WiFi domain returned by the SPLC method.\n"); + return 0; + } + +- return power_limit->integer.value; ++ dflt_pwr_limit = &data_pkg->package.elements[1]; ++ return dflt_pwr_limit->integer.value; + } + + static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev) + { + acpi_handle pxsx_handle; + acpi_handle handle; +- struct acpi_buffer splx = {ACPI_ALLOCATE_BUFFER, NULL}; ++ struct acpi_buffer splc = {ACPI_ALLOCATE_BUFFER, NULL}; + acpi_status status; + + pxsx_handle = ACPI_HANDLE(&pdev->dev); +@@ -578,23 +594,24 @@ static void set_dflt_pwr_limit(struct iw + } + + /* Get the method's handle */ +- status = acpi_get_handle(pxsx_handle, (acpi_string)SPL_METHOD, &handle); ++ status = acpi_get_handle(pxsx_handle, (acpi_string)ACPI_SPLC_METHOD, ++ &handle); + if (ACPI_FAILURE(status)) { +- IWL_DEBUG_INFO(trans, "SPL method not found\n"); ++ IWL_DEBUG_INFO(trans, "SPLC method not found\n"); + return; + } + + /* Call SPLC with no arguments */ +- status = acpi_evaluate_object(handle, NULL, NULL, &splx); ++ status = acpi_evaluate_object(handle, NULL, NULL, &splc); + if (ACPI_FAILURE(status)) { + IWL_ERR(trans, "SPLC invocation failed (0x%x)\n", status); + return; + } + +- trans->dflt_pwr_limit = splx_get_pwr_limit(trans, splx.pointer); ++ trans->dflt_pwr_limit = splc_get_pwr_limit(trans, splc.pointer); + IWL_DEBUG_INFO(trans, "Default power limit set to %lld\n", + trans->dflt_pwr_limit); +- kfree(splx.pointer); ++ kfree(splc.pointer); + } + + #else /* CONFIG_ACPI */ diff --git a/queue-4.8/iwlwifi-pcie-mark-command-queue-lock-with-separate-lockdep-class.patch b/queue-4.8/iwlwifi-pcie-mark-command-queue-lock-with-separate-lockdep-class.patch new file mode 100644 index 00000000000..7d193dce105 --- /dev/null +++ b/queue-4.8/iwlwifi-pcie-mark-command-queue-lock-with-separate-lockdep-class.patch @@ -0,0 +1,52 @@ +From faead41cc7213ccef5a58c1bf518ac24816fe8a6 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Thu, 22 Sep 2016 10:31:41 +0200 +Subject: iwlwifi: pcie: mark command queue lock with separate lockdep class + +From: Johannes Berg + +commit faead41cc7213ccef5a58c1bf518ac24816fe8a6 upstream. + +Emmanuel reports that when CMD_WANT_ASYNC_CALLBACK is used by mvm, +the callback will be called with the command queue lock held, and +mvm will try to stop all (other) TX queues, which acquires their +locks - this caused a false lockdep recursive locking report. + +Suppress this report by marking the command queue lock with a new, +separate, lock class so lockdep can tell the difference between +the two types of queues. + +Fixes: 156f92f2b471 ("iwlwifi: block the queues when we send ADD_STA for uAPSD") +Reported-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +Signed-off-by: Luca Coelho +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +@@ -522,6 +522,7 @@ error: + static int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq, + int slots_num, u32 txq_id) + { ++ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + int ret; + + txq->need_update = false; +@@ -536,6 +537,13 @@ static int iwl_pcie_txq_init(struct iwl_ + return ret; + + spin_lock_init(&txq->lock); ++ ++ if (txq_id == trans_pcie->cmd_queue) { ++ static struct lock_class_key iwl_pcie_cmd_queue_lock_class; ++ ++ lockdep_set_class(&txq->lock, &iwl_pcie_cmd_queue_lock_class); ++ } ++ + __skb_queue_head_init(&txq->overflow_q); + + /* diff --git a/queue-4.8/mfd-core-fix-device-reference-leak-in-mfd_clone_cell.patch b/queue-4.8/mfd-core-fix-device-reference-leak-in-mfd_clone_cell.patch new file mode 100644 index 00000000000..c8bc2002c06 --- /dev/null +++ b/queue-4.8/mfd-core-fix-device-reference-leak-in-mfd_clone_cell.patch @@ -0,0 +1,32 @@ +From 722f191080de641f023feaa7d5648caf377844f5 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 1 Nov 2016 11:38:18 +0100 +Subject: mfd: core: Fix device reference leak in mfd_clone_cell + +From: Johan Hovold + +commit 722f191080de641f023feaa7d5648caf377844f5 upstream. + +Make sure to drop the reference taken by bus_find_device_by_name() +before returning from mfd_clone_cell(). + +Fixes: a9bbba996302 ("mfd: add platform_device sharing support for mfd") +Signed-off-by: Johan Hovold +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mfd/mfd-core.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/mfd/mfd-core.c ++++ b/drivers/mfd/mfd-core.c +@@ -399,6 +399,8 @@ int mfd_clone_cell(const char *cell, con + clones[i]); + } + ++ put_device(dev); ++ + return 0; + } + EXPORT_SYMBOL(mfd_clone_cell); diff --git a/queue-4.8/netfilter-nft_dynset-fix-element-timeout-for-hz-1000.patch b/queue-4.8/netfilter-nft_dynset-fix-element-timeout-for-hz-1000.patch new file mode 100644 index 00000000000..d265918053e --- /dev/null +++ b/queue-4.8/netfilter-nft_dynset-fix-element-timeout-for-hz-1000.patch @@ -0,0 +1,48 @@ +From a8b1e36d0d1d6f51490e7adce35367ed6adb10e7 Mon Sep 17 00:00:00 2001 +From: "Anders K. Pedersen" +Date: Sun, 9 Oct 2016 13:49:02 +0000 +Subject: netfilter: nft_dynset: fix element timeout for HZ != 1000 + +From: Anders K. Pedersen + +commit a8b1e36d0d1d6f51490e7adce35367ed6adb10e7 upstream. + +With HZ=100 element timeout in dynamic sets (i.e. flow tables) is 10 times +higher than configured. + +Add proper conversion to/from jiffies, when interacting with userspace. + +I tested this on Linux 4.8.1, and it applies cleanly to current nf and +nf-next trees. + +Fixes: 22fe54d5fefc ("netfilter: nf_tables: add support for dynamic set updates") +Signed-off-by: Anders K. Pedersen +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nft_dynset.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/netfilter/nft_dynset.c ++++ b/net/netfilter/nft_dynset.c +@@ -143,7 +143,8 @@ static int nft_dynset_init(const struct + if (tb[NFTA_DYNSET_TIMEOUT] != NULL) { + if (!(set->flags & NFT_SET_TIMEOUT)) + return -EINVAL; +- timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT])); ++ timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64( ++ tb[NFTA_DYNSET_TIMEOUT]))); + } + + priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]); +@@ -230,7 +231,8 @@ static int nft_dynset_dump(struct sk_buf + goto nla_put_failure; + if (nla_put_string(skb, NFTA_DYNSET_SET_NAME, priv->set->name)) + goto nla_put_failure; +- if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, cpu_to_be64(priv->timeout), ++ if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, ++ cpu_to_be64(jiffies_to_msecs(priv->timeout)), + NFTA_DYNSET_PAD)) + goto nla_put_failure; + if (priv->expr && nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr)) diff --git a/queue-4.8/perf-hists-fix-column-length-on-hierarchy.patch b/queue-4.8/perf-hists-fix-column-length-on-hierarchy.patch new file mode 100644 index 00000000000..574b643ad6f --- /dev/null +++ b/queue-4.8/perf-hists-fix-column-length-on-hierarchy.patch @@ -0,0 +1,62 @@ +From c72ab446cac1d6c9551fd26c4cfef1b2fc5041fd Mon Sep 17 00:00:00 2001 +From: Namhyung Kim +Date: Tue, 8 Nov 2016 22:08:33 +0900 +Subject: perf hists: Fix column length on --hierarchy + +From: Namhyung Kim + +commit c72ab446cac1d6c9551fd26c4cfef1b2fc5041fd upstream. + +Markus reported that there's a weird behavior on perf top --hierarchy +regarding the column length. + +Looking at the code, I found a dubious code which affects the symptoms. +When --hierarchy option is used, the last column length might be +inaccurate since it skips to update the length on leaf entries. + +I cannot remember why it did and looks like a leftover from previous +version during the development. + +Anyway, updating the column length often is not harmful. So let's move +the code out. + +Reported-and-Tested-by: Markus Trippelsdorf +Signed-off-by: Namhyung Kim +Cc: Jiri Olsa +Cc: Peter Zijlstra +Fixes: 1a3906a7e6b9 ("perf hists: Resort hist entries with hierarchy") +Link: http://lkml.kernel.org/r/20161108130833.9263-5-namhyung@kernel.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/util/hist.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/tools/perf/util/hist.c ++++ b/tools/perf/util/hist.c +@@ -1596,18 +1596,18 @@ static void hists__hierarchy_output_reso + if (prog) + ui_progress__update(prog, 1); + ++ hists->nr_entries++; ++ if (!he->filtered) { ++ hists->nr_non_filtered_entries++; ++ hists__calc_col_len(hists, he); ++ } ++ + if (!he->leaf) { + hists__hierarchy_output_resort(hists, prog, + &he->hroot_in, + &he->hroot_out, + min_callchain_hits, + use_callchain); +- hists->nr_entries++; +- if (!he->filtered) { +- hists->nr_non_filtered_entries++; +- hists__calc_col_len(hists, he); +- } +- + continue; + } + diff --git a/queue-4.8/pm-sleep-don-t-suspend-parent-when-async-child-suspend_-noirq-late-fails.patch b/queue-4.8/pm-sleep-don-t-suspend-parent-when-async-child-suspend_-noirq-late-fails.patch new file mode 100644 index 00000000000..03c42296a43 --- /dev/null +++ b/queue-4.8/pm-sleep-don-t-suspend-parent-when-async-child-suspend_-noirq-late-fails.patch @@ -0,0 +1,77 @@ +From 6f75c3fd56daf547d684127a7f83c283c3c160d1 Mon Sep 17 00:00:00 2001 +From: Brian Norris +Date: Wed, 9 Nov 2016 17:21:08 -0800 +Subject: PM / sleep: don't suspend parent when async child suspend_{noirq, late} fails + +From: Brian Norris + +commit 6f75c3fd56daf547d684127a7f83c283c3c160d1 upstream. + +Consider two devices, A and B, where B is a child of A, and B utilizes +asynchronous suspend (it does not matter whether A is sync or async). If +B fails to suspend_noirq() or suspend_late(), or is interrupted by a +wakeup (pm_wakeup_pending()), then it aborts and sets the async_error +variable. However, device A does not (immediately) check the async_error +variable; it may continue to run its own suspend_noirq()/suspend_late() +callback. This is bad. + +We can resolve this problem by doing our error and wakeup checking +(particularly, for the async_error flag) after waiting for children to +suspend, instead of before. This also helps align the logic for the noirq and +late suspend cases with the logic in __device_suspend(). + +It's easy to observe this erroneous behavior by, for example, forcing a +device to sleep a bit in its suspend_noirq() (to ensure the parent is +waiting for the child to complete), then return an error, and watch the +parent suspend_noirq() still get called. (Or similarly, fake a wakeup +event at the right (or is it wrong?) time.) + +Fixes: de377b397272 (PM / sleep: Asynchronous threads for suspend_late) +Fixes: 28b6fd6e3779 (PM / sleep: Asynchronous threads for suspend_noirq) +Reported-by: Jeffy Chen +Signed-off-by: Brian Norris +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/power/main.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/base/power/main.c ++++ b/drivers/base/power/main.c +@@ -1027,6 +1027,8 @@ static int __device_suspend_noirq(struct + TRACE_DEVICE(dev); + TRACE_SUSPEND(0); + ++ dpm_wait_for_children(dev, async); ++ + if (async_error) + goto Complete; + +@@ -1038,8 +1040,6 @@ static int __device_suspend_noirq(struct + if (dev->power.syscore || dev->power.direct_complete) + goto Complete; + +- dpm_wait_for_children(dev, async); +- + if (dev->pm_domain) { + info = "noirq power domain "; + callback = pm_noirq_op(&dev->pm_domain->ops, state); +@@ -1174,6 +1174,8 @@ static int __device_suspend_late(struct + + __pm_runtime_disable(dev, false); + ++ dpm_wait_for_children(dev, async); ++ + if (async_error) + goto Complete; + +@@ -1185,8 +1187,6 @@ static int __device_suspend_late(struct + if (dev->power.syscore || dev->power.direct_complete) + goto Complete; + +- dpm_wait_for_children(dev, async); +- + if (dev->pm_domain) { + info = "late power domain "; + callback = pm_late_early_op(&dev->pm_domain->ops, state); diff --git a/queue-4.8/pm-sleep-fix-device-reference-leak-in-test_suspend.patch b/queue-4.8/pm-sleep-fix-device-reference-leak-in-test_suspend.patch new file mode 100644 index 00000000000..d96b53facd0 --- /dev/null +++ b/queue-4.8/pm-sleep-fix-device-reference-leak-in-test_suspend.patch @@ -0,0 +1,35 @@ +From ceb75787bc75d0a7b88519ab8a68067ac690f55a Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 1 Nov 2016 11:49:56 +0100 +Subject: PM / sleep: fix device reference leak in test_suspend + +From: Johan Hovold + +commit ceb75787bc75d0a7b88519ab8a68067ac690f55a upstream. + +Make sure to drop the reference taken by class_find_device() after +opening the RTC device. + +Fixes: 77437fd4e61f (pm: boot time suspend selftest) +Signed-off-by: Johan Hovold +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/power/suspend_test.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/kernel/power/suspend_test.c ++++ b/kernel/power/suspend_test.c +@@ -203,8 +203,10 @@ static int __init test_suspend(void) + + /* RTCs have initialized by now too ... can we use one? */ + dev = class_find_device(rtc_class, NULL, NULL, has_wakealarm); +- if (dev) ++ if (dev) { + rtc = rtc_class_open(dev_name(dev)); ++ put_device(dev); ++ } + if (!rtc) { + printk(warn_no_rtc); + return 0; diff --git a/queue-4.8/rtc-omap-fix-selecting-external-osc.patch b/queue-4.8/rtc-omap-fix-selecting-external-osc.patch new file mode 100644 index 00000000000..367fed2901a --- /dev/null +++ b/queue-4.8/rtc-omap-fix-selecting-external-osc.patch @@ -0,0 +1,67 @@ +From 3984903a2e3906d3def220e688040ce93368200a Mon Sep 17 00:00:00 2001 +From: Lokesh Vutla +Date: Thu, 27 Oct 2016 11:27:25 +0530 +Subject: rtc: omap: Fix selecting external osc + +From: Lokesh Vutla + +commit 3984903a2e3906d3def220e688040ce93368200a upstream. + +RTC can be clocked from an external 32KHz oscillator, or from the +Peripheral PLL. The RTC has an internal oscillator buffer to support +direct operation with a crystal. + + ---------------------------------------- + | Device --------- | + | | | | + | | RTCSS | | + | --------- | | | + OSC |<------| RTC | | | | + |------>| OSC |--- | | | + | -------- | | | | + | ----|clk | | + | -------- | | | | + | | PRCM |--- | | | + | -------- -------- | + ---------------------------------------- + +The RTC functional clock is sourced by default from the clock derived +from the Peripheral PLL. In order to select source as external osc clk +the following changes needs to be done: +- Enable the RTC OSC (RTC_OSC_REG[4]OSC32K_GZ = 0) +- Enable the clock mux(RTC_OSC_REG[6]K32CLK_EN = 1) +- Select the external clock source (RTC_OSC_REG[3]32KCLK_SEL = 1) + +Fixes: 399cf0f63f6f2 ("rtc: omap: Add external clock enabling support") +Signed-off-by: Keerthy +Signed-off-by: Lokesh Vutla +Signed-off-by: Dave Gerlach +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-omap.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/rtc/rtc-omap.c ++++ b/drivers/rtc/rtc-omap.c +@@ -109,6 +109,7 @@ + /* OMAP_RTC_OSC_REG bit fields: */ + #define OMAP_RTC_OSC_32KCLK_EN BIT(6) + #define OMAP_RTC_OSC_SEL_32KCLK_SRC BIT(3) ++#define OMAP_RTC_OSC_OSC32K_GZ_DISABLE BIT(4) + + /* OMAP_RTC_IRQWAKEEN bit fields: */ + #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1) +@@ -646,8 +647,9 @@ static int omap_rtc_probe(struct platfor + */ + if (rtc->has_ext_clk) { + reg = rtc_read(rtc, OMAP_RTC_OSC_REG); +- rtc_write(rtc, OMAP_RTC_OSC_REG, +- reg | OMAP_RTC_OSC_SEL_32KCLK_SRC); ++ reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE; ++ reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC; ++ rtc_writel(rtc, OMAP_RTC_OSC_REG, reg); + } + + rtc->type->lock(rtc); diff --git a/queue-4.8/series b/queue-4.8/series index da428c3a452..e0dec938ba4 100644 --- a/queue-4.8/series +++ b/queue-4.8/series @@ -32,3 +32,35 @@ drm-amdgpu-attach-exclusive-fence-to-prime-exported-bo-s.-v5.patch drm-i915-refresh-that-status-of-mst-capable-connectors-in-detect.patch drm-i915-assume-non-dp-port-if-dvo_port-is-hdmi-and-there-s-no-aux-ch-specified-in-the-vbt.patch virtio-net-drop-legacy-features-in-virtio-1-mode.patch +clk-mmp-pxa910-fix-return-value-check-in-pxa910_clk_init.patch +clk-mmp-pxa168-fix-return-value-check-in-pxa168_clk_init.patch +clk-mmp-mmp2-fix-return-value-check-in-mmp2_clk_init.patch +clk-imx-fix-integer-overflow-in-av-pll-round-rate.patch +rtc-omap-fix-selecting-external-osc.patch +iwlwifi-pcie-fix-splc-structure-parsing.patch +iwlwifi-pcie-mark-command-queue-lock-with-separate-lockdep-class.patch +iwlwifi-mvm-fix-netdetect-starting-stopping-for-unified-images.patch +iwlwifi-mvm-fix-d3_test-with-unified-d0-d3-images.patch +iwlwifi-mvm-wake-the-wait-queue-when-the-rx-sync-counter-is-zero.patch +mfd-core-fix-device-reference-leak-in-mfd_clone_cell.patch +sunrpc-svc_age_temp_xprts_now-should-not-call-setsockopt-non-tcp-transports.patch +uwb-fix-device-reference-leaks.patch +pm-sleep-fix-device-reference-leak-in-test_suspend.patch +pm-sleep-don-t-suspend-parent-when-async-child-suspend_-noirq-late-fails.patch +perf-hists-fix-column-length-on-hierarchy.patch +ib-rxe-update-qp-state-for-user-query.patch +ib-rxe-fix-kernel-panic-in-udp-tunnel-with-gro-and-rx-checksum.patch +ib-rxe-fix-handling-of-erroneous-wr.patch +ib-rxe-clear-queue-buffer-when-modifying-qp-to-reset.patch +ib-mlx4-check-gid_index-return-value.patch +ib-mlx4-fix-create-cq-error-flow.patch +ib-mlx5-validate-requested-rqt-size.patch +ib-mlx5-use-cache-line-size-to-select-cqe-stride.patch +ib-mlx5-fix-memory-leak-in-query-device.patch +ib-mlx5-fix-fatal-error-dispatching.patch +ib-mlx5-fix-null-pointer-dereference-on-debug-print.patch +ib-core-avoid-unsigned-int-overflow-in-sg_alloc_table.patch +ib-hfi1-remove-incorrect-is_err-check.patch +ib-uverbs-fix-leak-of-xrc-target-qps.patch +ib-cm-mark-stale-cm-id-s-whenever-the-mad-agent-was-unregistered.patch +netfilter-nft_dynset-fix-element-timeout-for-hz-1000.patch diff --git a/queue-4.8/sunrpc-svc_age_temp_xprts_now-should-not-call-setsockopt-non-tcp-transports.patch b/queue-4.8/sunrpc-svc_age_temp_xprts_now-should-not-call-setsockopt-non-tcp-transports.patch new file mode 100644 index 00000000000..483c0353ee6 --- /dev/null +++ b/queue-4.8/sunrpc-svc_age_temp_xprts_now-should-not-call-setsockopt-non-tcp-transports.patch @@ -0,0 +1,205 @@ +From ea08e39230e898844d9de5b60cdbb30067cebfe7 Mon Sep 17 00:00:00 2001 +From: Scott Mayhew +Date: Fri, 11 Nov 2016 13:16:22 -0500 +Subject: sunrpc: svc_age_temp_xprts_now should not call setsockopt non-tcp transports + +From: Scott Mayhew + +commit ea08e39230e898844d9de5b60cdbb30067cebfe7 upstream. + +This fixes the following panic that can occur with NFSoRDMA. + +general protection fault: 0000 [#1] SMP +Modules linked in: rpcrdma ib_isert iscsi_target_mod ib_iser libiscsi +scsi_transport_iscsi ib_srpt target_core_mod ib_srp scsi_transport_srp +scsi_tgt ib_ipoib rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm +mlx5_ib ib_core intel_powerclamp coretemp kvm_intel kvm sg ioatdma +ipmi_devintf ipmi_ssif dcdbas iTCO_wdt iTCO_vendor_support pcspkr +irqbypass sb_edac shpchp dca crc32_pclmul ghash_clmulni_intel edac_core +lpc_ich aesni_intel lrw gf128mul glue_helper ablk_helper mei_me mei +ipmi_si cryptd wmi ipmi_msghandler acpi_pad acpi_power_meter nfsd +auth_rpcgss nfs_acl lockd grace sunrpc ip_tables xfs libcrc32c sd_mod +crc_t10dif crct10dif_generic mgag200 i2c_algo_bit drm_kms_helper +syscopyarea sysfillrect sysimgblt ahci fb_sys_fops ttm libahci mlx5_core +tg3 crct10dif_pclmul drm crct10dif_common +ptp i2c_core libata crc32c_intel pps_core fjes dm_mirror dm_region_hash +dm_log dm_mod +CPU: 1 PID: 120 Comm: kworker/1:1 Not tainted 3.10.0-514.el7.x86_64 #1 +Hardware name: Dell Inc. PowerEdge R320/0KM5PX, BIOS 2.4.2 01/29/2015 +Workqueue: events check_lifetime +task: ffff88031f506dd0 ti: ffff88031f584000 task.ti: ffff88031f584000 +RIP: 0010:[] [] +_raw_spin_lock_bh+0x17/0x50 +RSP: 0018:ffff88031f587ba8 EFLAGS: 00010206 +RAX: 0000000000020000 RBX: 20041fac02080072 RCX: ffff88031f587fd8 +RDX: 0000000000000000 RSI: 0000000000000000 RDI: 20041fac02080072 +RBP: ffff88031f587bb0 R08: 0000000000000008 R09: ffffffff8155be77 +R10: ffff880322a59b00 R11: ffffea000bf39f00 R12: 20041fac02080072 +R13: 000000000000000d R14: ffff8800c4fbd800 R15: 0000000000000001 +FS: 0000000000000000(0000) GS:ffff880322a40000(0000) +knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f3c52d4547e CR3: 00000000019ba000 CR4: 00000000001407e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +Stack: +20041fac02080002 ffff88031f587bd0 ffffffff81557830 20041fac02080002 +ffff88031f587c78 ffff88031f587c40 ffffffff8155ae08 000000010157df32 +0000000800000001 ffff88031f587c20 ffffffff81096acb ffffffff81aa37d0 +Call Trace: +[] lock_sock_nested+0x20/0x50 +[] sock_setsockopt+0x78/0x940 +[] ? lock_timer_base.isra.33+0x2b/0x50 +[] kernel_setsockopt+0x4d/0x50 +[] svc_age_temp_xprts_now+0x174/0x1e0 [sunrpc] +[] nfsd_inetaddr_event+0x9d/0xd0 [nfsd] +[] notifier_call_chain+0x4c/0x70 +[] __blocking_notifier_call_chain+0x4d/0x70 +[] blocking_notifier_call_chain+0x16/0x20 +[] __inet_del_ifa+0x168/0x2d0 +[] check_lifetime+0x25f/0x270 +[] process_one_work+0x17b/0x470 +[] worker_thread+0x126/0x410 +[] ? rescuer_thread+0x460/0x460 +[] kthread+0xcf/0xe0 +[] ? kthread_create_on_node+0x140/0x140 +[] ret_from_fork+0x58/0x90 +[] ? kthread_create_on_node+0x140/0x140 +Code: ca 75 f1 5d c3 0f 1f 80 00 00 00 00 eb d9 66 0f 1f 44 00 00 0f 1f +44 00 00 55 48 89 e5 53 48 89 fb e8 7e 04 a0 ff b8 00 00 02 00 0f +c1 03 89 c2 c1 ea 10 66 39 c2 75 03 5b 5d c3 83 e2 fe 0f +RIP [] _raw_spin_lock_bh+0x17/0x50 +RSP + +Signed-off-by: Scott Mayhew +Fixes: c3d4879e ("sunrpc: Add a function to close temporary transports immediately") +Reviewed-by: Chuck Lever +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/sunrpc/svc_xprt.h | 1 + + net/sunrpc/svc_xprt.c | 11 +---------- + net/sunrpc/svcsock.c | 21 +++++++++++++++++++++ + net/sunrpc/xprtrdma/svc_rdma_transport.c | 6 ++++++ + 4 files changed, 29 insertions(+), 10 deletions(-) + +--- a/include/linux/sunrpc/svc_xprt.h ++++ b/include/linux/sunrpc/svc_xprt.h +@@ -25,6 +25,7 @@ struct svc_xprt_ops { + void (*xpo_detach)(struct svc_xprt *); + void (*xpo_free)(struct svc_xprt *); + int (*xpo_secure_port)(struct svc_rqst *); ++ void (*xpo_kill_temp_xprt)(struct svc_xprt *); + }; + + struct svc_xprt_class { +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -1002,14 +1002,8 @@ static void svc_age_temp_xprts(unsigned + void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr) + { + struct svc_xprt *xprt; +- struct svc_sock *svsk; +- struct socket *sock; + struct list_head *le, *next; + LIST_HEAD(to_be_closed); +- struct linger no_linger = { +- .l_onoff = 1, +- .l_linger = 0, +- }; + + spin_lock_bh(&serv->sv_lock); + list_for_each_safe(le, next, &serv->sv_tempsocks) { +@@ -1027,10 +1021,7 @@ void svc_age_temp_xprts_now(struct svc_s + list_del_init(le); + xprt = list_entry(le, struct svc_xprt, xpt_list); + dprintk("svc_age_temp_xprts_now: closing %p\n", xprt); +- svsk = container_of(xprt, struct svc_sock, sk_xprt); +- sock = svsk->sk_sock; +- kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER, +- (char *)&no_linger, sizeof(no_linger)); ++ xprt->xpt_ops->xpo_kill_temp_xprt(xprt); + svc_close_xprt(xprt); + } + } +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -438,6 +438,21 @@ static int svc_tcp_has_wspace(struct svc + return !test_bit(SOCK_NOSPACE, &svsk->sk_sock->flags); + } + ++static void svc_tcp_kill_temp_xprt(struct svc_xprt *xprt) ++{ ++ struct svc_sock *svsk; ++ struct socket *sock; ++ struct linger no_linger = { ++ .l_onoff = 1, ++ .l_linger = 0, ++ }; ++ ++ svsk = container_of(xprt, struct svc_sock, sk_xprt); ++ sock = svsk->sk_sock; ++ kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER, ++ (char *)&no_linger, sizeof(no_linger)); ++} ++ + /* + * See net/ipv6/ip_sockglue.c : ip_cmsg_recv_pktinfo + */ +@@ -648,6 +663,10 @@ static struct svc_xprt *svc_udp_accept(s + return NULL; + } + ++static void svc_udp_kill_temp_xprt(struct svc_xprt *xprt) ++{ ++} ++ + static struct svc_xprt *svc_udp_create(struct svc_serv *serv, + struct net *net, + struct sockaddr *sa, int salen, +@@ -667,6 +686,7 @@ static struct svc_xprt_ops svc_udp_ops = + .xpo_has_wspace = svc_udp_has_wspace, + .xpo_accept = svc_udp_accept, + .xpo_secure_port = svc_sock_secure_port, ++ .xpo_kill_temp_xprt = svc_udp_kill_temp_xprt, + }; + + static struct svc_xprt_class svc_udp_class = { +@@ -1242,6 +1262,7 @@ static struct svc_xprt_ops svc_tcp_ops = + .xpo_has_wspace = svc_tcp_has_wspace, + .xpo_accept = svc_tcp_accept, + .xpo_secure_port = svc_sock_secure_port, ++ .xpo_kill_temp_xprt = svc_tcp_kill_temp_xprt, + }; + + static struct svc_xprt_class svc_tcp_class = { +--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c ++++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c +@@ -67,6 +67,7 @@ static void svc_rdma_detach(struct svc_x + static void svc_rdma_free(struct svc_xprt *xprt); + static int svc_rdma_has_wspace(struct svc_xprt *xprt); + static int svc_rdma_secure_port(struct svc_rqst *); ++static void svc_rdma_kill_temp_xprt(struct svc_xprt *); + + static struct svc_xprt_ops svc_rdma_ops = { + .xpo_create = svc_rdma_create, +@@ -79,6 +80,7 @@ static struct svc_xprt_ops svc_rdma_ops + .xpo_has_wspace = svc_rdma_has_wspace, + .xpo_accept = svc_rdma_accept, + .xpo_secure_port = svc_rdma_secure_port, ++ .xpo_kill_temp_xprt = svc_rdma_kill_temp_xprt, + }; + + struct svc_xprt_class svc_rdma_class = { +@@ -1285,6 +1287,10 @@ static int svc_rdma_secure_port(struct s + return 1; + } + ++static void svc_rdma_kill_temp_xprt(struct svc_xprt *xprt) ++{ ++} ++ + int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr) + { + struct ib_send_wr *bad_wr, *n_wr; diff --git a/queue-4.8/uwb-fix-device-reference-leaks.patch b/queue-4.8/uwb-fix-device-reference-leaks.patch new file mode 100644 index 00000000000..55b137c9d89 --- /dev/null +++ b/queue-4.8/uwb-fix-device-reference-leaks.patch @@ -0,0 +1,86 @@ +From d6124b409ca33c100170ffde51cd8dff761454a1 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 1 Nov 2016 12:13:31 +0100 +Subject: uwb: fix device reference leaks + +From: Johan Hovold + +commit d6124b409ca33c100170ffde51cd8dff761454a1 upstream. + +This subsystem consistently fails to drop the device reference taken by +class_find_device(). + +Note that some of these lookup functions already take a reference to the +returned data, while others claim no reference is needed (or does not +seem need one). + +Fixes: 183b9b592a62 ("uwb: add the UWB stack (core files)") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/uwb/lc-rc.c | 16 +++++++++++++--- + drivers/uwb/pal.c | 2 ++ + 2 files changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/uwb/lc-rc.c ++++ b/drivers/uwb/lc-rc.c +@@ -56,8 +56,11 @@ static struct uwb_rc *uwb_rc_find_by_ind + struct uwb_rc *rc = NULL; + + dev = class_find_device(&uwb_rc_class, NULL, &index, uwb_rc_index_match); +- if (dev) ++ if (dev) { + rc = dev_get_drvdata(dev); ++ put_device(dev); ++ } ++ + return rc; + } + +@@ -467,7 +470,9 @@ struct uwb_rc *__uwb_rc_try_get(struct u + if (dev) { + rc = dev_get_drvdata(dev); + __uwb_rc_get(rc); ++ put_device(dev); + } ++ + return rc; + } + EXPORT_SYMBOL_GPL(__uwb_rc_try_get); +@@ -520,8 +525,11 @@ struct uwb_rc *uwb_rc_get_by_grandpa(con + + dev = class_find_device(&uwb_rc_class, NULL, grandpa_dev, + find_rc_grandpa); +- if (dev) ++ if (dev) { + rc = dev_get_drvdata(dev); ++ put_device(dev); ++ } ++ + return rc; + } + EXPORT_SYMBOL_GPL(uwb_rc_get_by_grandpa); +@@ -553,8 +561,10 @@ struct uwb_rc *uwb_rc_get_by_dev(const s + struct uwb_rc *rc = NULL; + + dev = class_find_device(&uwb_rc_class, NULL, addr, find_rc_dev); +- if (dev) ++ if (dev) { + rc = dev_get_drvdata(dev); ++ put_device(dev); ++ } + + return rc; + } +--- a/drivers/uwb/pal.c ++++ b/drivers/uwb/pal.c +@@ -97,6 +97,8 @@ static bool uwb_rc_class_device_exists(s + + dev = class_find_device(&uwb_rc_class, NULL, target_rc, find_rc); + ++ put_device(dev); ++ + return (dev != NULL); + } +