From: Greg Kroah-Hartman Date: Thu, 12 Mar 2015 14:16:29 +0000 (+0100) Subject: 3.19-stable patches X-Git-Tag: v3.10.72~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=66e34d0ad0b319d4395b12d750c38c455503eee8;p=thirdparty%2Fkernel%2Fstable-queue.git 3.19-stable patches added patches: ib-core-fix-deadlock-on-uverbs-modify_qp-error-flow.patch ib-core-properly-handle-registration-of-on-demand-paging-mrs-after-dereg.patch ib-core-when-marshaling-ucma-path-from-user-space-clear-unused-fields.patch ib-iser-fix-memory-regions-possible-leak.patch ib-iser-use-correct-dma-direction-when-unmapping-sgs.patch ib-mlx4-fix-memory-leak-in-__mlx4_ib_modify_qp.patch ib-mlx4-fix-wrong-usage-of-ipv4-protocol-for-multicast-attach-detach.patch ib-mlx5-fix-error-code-in-get_port_caps.patch ib-qib-do-not-write-eeprom.patch locking-rtmutex-avoid-a-null-pointer-dereference-on-deadlock.patch sg-fix-read-error-reporting.patch --- diff --git a/queue-3.19/ib-core-fix-deadlock-on-uverbs-modify_qp-error-flow.patch b/queue-3.19/ib-core-fix-deadlock-on-uverbs-modify_qp-error-flow.patch new file mode 100644 index 00000000000..144ae2b9575 --- /dev/null +++ b/queue-3.19/ib-core-fix-deadlock-on-uverbs-modify_qp-error-flow.patch @@ -0,0 +1,51 @@ +From 0fb8bcf022f19a375d7c4bd79ac513da8ae6d78b Mon Sep 17 00:00:00 2001 +From: Moshe Lazer +Date: Thu, 5 Feb 2015 13:53:52 +0200 +Subject: IB/core: Fix deadlock on uverbs modify_qp error flow + +From: Moshe Lazer + +commit 0fb8bcf022f19a375d7c4bd79ac513da8ae6d78b upstream. + +The deadlock occurs in __uverbs_modify_qp: we take a lock (idr_read_qp) +and in case of failure in ib_resolve_eth_l2_attrs we don't release +it (put_qp_read). Fix that. + +Fixes: ed4c54e5b4ba ("IB/core: Resolve Ethernet L2 addresses when modifying QP") +Signed-off-by: Moshe Lazer +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/uverbs_cmd.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -2091,20 +2091,21 @@ ssize_t ib_uverbs_modify_qp(struct ib_uv + if (qp->real_qp == qp) { + ret = ib_resolve_eth_l2_attrs(qp, attr, &cmd.attr_mask); + if (ret) +- goto out; ++ goto release_qp; + ret = qp->device->modify_qp(qp, attr, + modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata); + } else { + ret = ib_modify_qp(qp, attr, modify_qp_mask(qp->qp_type, cmd.attr_mask)); + } + +- put_qp_read(qp); +- + if (ret) +- goto out; ++ goto release_qp; + + ret = in_len; + ++release_qp: ++ put_qp_read(qp); ++ + out: + kfree(attr); + diff --git a/queue-3.19/ib-core-properly-handle-registration-of-on-demand-paging-mrs-after-dereg.patch b/queue-3.19/ib-core-properly-handle-registration-of-on-demand-paging-mrs-after-dereg.patch new file mode 100644 index 00000000000..c02b4f803bf --- /dev/null +++ b/queue-3.19/ib-core-properly-handle-registration-of-on-demand-paging-mrs-after-dereg.patch @@ -0,0 +1,44 @@ +From 4fc701ead77ede96df3e8b3de13fdf2b1326ee5b Mon Sep 17 00:00:00 2001 +From: Haggai Eran +Date: Tue, 6 Jan 2015 13:56:02 +0200 +Subject: IB/core: Properly handle registration of on-demand paging MRs after dereg + +From: Haggai Eran + +commit 4fc701ead77ede96df3e8b3de13fdf2b1326ee5b upstream. + +When the last on-demand paging MR is released the notifier count is +left non-zero so that concurrent page faults will have to abort. If a +new MR is then registered, the counter is reset. However, the decision +is made to put the new MR in the list waiting for the notifier count +to reach zero, before the counter is reset. An invalidation or another +MR registration can release the MR to handle page faults, but without +such an event the MR can wait forever. + +The patch fixes this issue by adding a check whether the MR is the +first on-demand paging MR when deciding whether it is ready to handle +page faults. If it is the first MR, we know that there are no mmu +notifiers running in parallel to the registration. + +Fixes: 882214e2b128 ("IB/core: Implement support for MMU notifiers regarding on demand paging regions") +Signed-off-by: Haggai Eran +Signed-off-by: Shachar Raindel +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/umem_odp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/core/umem_odp.c ++++ b/drivers/infiniband/core/umem_odp.c +@@ -294,7 +294,8 @@ int ib_umem_odp_get(struct ib_ucontext * + if (likely(ib_umem_start(umem) != ib_umem_end(umem))) + rbt_ib_umem_insert(&umem->odp_data->interval_tree, + &context->umem_tree); +- if (likely(!atomic_read(&context->notifier_count))) ++ if (likely(!atomic_read(&context->notifier_count)) || ++ context->odp_mrs_count == 1) + umem->odp_data->mn_counters_active = true; + else + list_add(&umem->odp_data->no_private_counters, diff --git a/queue-3.19/ib-core-when-marshaling-ucma-path-from-user-space-clear-unused-fields.patch b/queue-3.19/ib-core-when-marshaling-ucma-path-from-user-space-clear-unused-fields.patch new file mode 100644 index 00000000000..c35400a8840 --- /dev/null +++ b/queue-3.19/ib-core-when-marshaling-ucma-path-from-user-space-clear-unused-fields.patch @@ -0,0 +1,37 @@ +From c2be9dc0e0fa59cc43c2c7084fc42b430809a0fe Mon Sep 17 00:00:00 2001 +From: Ilya Nelkenbaum +Date: Thu, 5 Feb 2015 13:53:48 +0200 +Subject: IB/core: When marshaling ucma path from user-space, clear unused fields + +From: Ilya Nelkenbaum + +commit c2be9dc0e0fa59cc43c2c7084fc42b430809a0fe upstream. + +When marshaling a user path to the kernel struct ib_sa_path, we need +to zero smac and dmac and set the vlan id to the "no vlan" value. + +This is to ensure that Ethernet attributes are not used with +InfiniBand QPs. + +Fixes: dd5f03beb4f7 ("IB/core: Ethernet L2 attributes in verbs/cm structures") +Signed-off-by: Ilya Nelkenbaum +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/ucma.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/infiniband/core/ucma.c ++++ b/drivers/infiniband/core/ucma.c +@@ -1124,6 +1124,9 @@ static int ucma_set_ib_path(struct ucma_ + if (!optlen) + return -EINVAL; + ++ memset(&sa_path, 0, sizeof(sa_path)); ++ sa_path.vlan_id = 0xffff; ++ + ib_sa_unpack_path(path_data->path_rec, &sa_path); + ret = rdma_set_ib_paths(ctx->cm_id, &sa_path, 1); + if (ret) diff --git a/queue-3.19/ib-iser-fix-memory-regions-possible-leak.patch b/queue-3.19/ib-iser-fix-memory-regions-possible-leak.patch new file mode 100644 index 00000000000..42d6c1bb9b9 --- /dev/null +++ b/queue-3.19/ib-iser-fix-memory-regions-possible-leak.patch @@ -0,0 +1,118 @@ +From 6606e6a2ff2710b473838b291dc533cd8fc1471f Mon Sep 17 00:00:00 2001 +From: Sagi Grimberg +Date: Sun, 18 Jan 2015 16:51:06 +0200 +Subject: IB/iser: Fix memory regions possible leak + +From: Sagi Grimberg + +commit 6606e6a2ff2710b473838b291dc533cd8fc1471f upstream. + +When teardown process starts during live IO, we need to keep the +memory regions pool (frmr/fmr) until all in-flight tasks are properly +released, since each task may return a memory region to the pool. In +order to do this, we pass a destroy flag to iser_free_ib_conn_res to +indicate we can destroy the device and the memory regions +pool. iser_conn_release will pass it as true and also DEVICE_REMOVAL +event (we need to let the device to properly remove). + +Also, Since we conditionally call iser_free_rx_descriptors, +remove the extra check on iser_conn->rx_descs. + +Fixes: 5426b1711fd0 ("IB/iser: Collapse cleanup and disconnect handlers") +Reported-by: Or Gerlitz +Signed-off-by: Sagi Grimberg +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/iser/iser_initiator.c | 4 ---- + drivers/infiniband/ulp/iser/iser_verbs.c | 25 ++++++++++++++----------- + 2 files changed, 14 insertions(+), 15 deletions(-) + +--- a/drivers/infiniband/ulp/iser/iser_initiator.c ++++ b/drivers/infiniband/ulp/iser/iser_initiator.c +@@ -320,9 +320,6 @@ void iser_free_rx_descriptors(struct ise + struct ib_conn *ib_conn = &iser_conn->ib_conn; + struct iser_device *device = ib_conn->device; + +- if (!iser_conn->rx_descs) +- goto free_login_buf; +- + if (device->iser_free_rdma_reg_res) + device->iser_free_rdma_reg_res(ib_conn); + +@@ -334,7 +331,6 @@ void iser_free_rx_descriptors(struct ise + /* make sure we never redo any unmapping */ + iser_conn->rx_descs = NULL; + +-free_login_buf: + iser_free_login_buf(iser_conn); + } + +--- a/drivers/infiniband/ulp/iser/iser_verbs.c ++++ b/drivers/infiniband/ulp/iser/iser_verbs.c +@@ -600,16 +600,16 @@ void iser_release_work(struct work_struc + /** + * iser_free_ib_conn_res - release IB related resources + * @iser_conn: iser connection struct +- * @destroy_device: indicator if we need to try to release +- * the iser device (only iscsi shutdown and DEVICE_REMOVAL +- * will use this. ++ * @destroy: indicator if we need to try to release the ++ * iser device and memory regoins pool (only iscsi ++ * shutdown and DEVICE_REMOVAL will use this). + * + * This routine is called with the iser state mutex held + * so the cm_id removal is out of here. It is Safe to + * be invoked multiple times. + */ + static void iser_free_ib_conn_res(struct iser_conn *iser_conn, +- bool destroy_device) ++ bool destroy) + { + struct ib_conn *ib_conn = &iser_conn->ib_conn; + struct iser_device *device = ib_conn->device; +@@ -617,17 +617,20 @@ static void iser_free_ib_conn_res(struct + iser_info("freeing conn %p cma_id %p qp %p\n", + iser_conn, ib_conn->cma_id, ib_conn->qp); + +- iser_free_rx_descriptors(iser_conn); +- + if (ib_conn->qp != NULL) { + ib_conn->comp->active_qps--; + rdma_destroy_qp(ib_conn->cma_id); + ib_conn->qp = NULL; + } + +- if (destroy_device && device != NULL) { +- iser_device_try_release(device); +- ib_conn->device = NULL; ++ if (destroy) { ++ if (iser_conn->rx_descs) ++ iser_free_rx_descriptors(iser_conn); ++ ++ if (device != NULL) { ++ iser_device_try_release(device); ++ ib_conn->device = NULL; ++ } + } + } + +@@ -840,7 +843,7 @@ static void iser_disconnected_handler(st + } + + static void iser_cleanup_handler(struct rdma_cm_id *cma_id, +- bool destroy_device) ++ bool destroy) + { + struct iser_conn *iser_conn = (struct iser_conn *)cma_id->context; + +@@ -850,7 +853,7 @@ static void iser_cleanup_handler(struct + * and flush errors. + */ + iser_disconnected_handler(cma_id); +- iser_free_ib_conn_res(iser_conn, destroy_device); ++ iser_free_ib_conn_res(iser_conn, destroy); + complete(&iser_conn->ib_completion); + }; + diff --git a/queue-3.19/ib-iser-use-correct-dma-direction-when-unmapping-sgs.patch b/queue-3.19/ib-iser-use-correct-dma-direction-when-unmapping-sgs.patch new file mode 100644 index 00000000000..22e06a3fdb0 --- /dev/null +++ b/queue-3.19/ib-iser-use-correct-dma-direction-when-unmapping-sgs.patch @@ -0,0 +1,96 @@ +From c6c95ef4cec680f7a10aa425a9970744b35b6489 Mon Sep 17 00:00:00 2001 +From: Roi Dayan +Date: Sun, 28 Dec 2014 14:26:11 +0200 +Subject: IB/iser: Use correct dma direction when unmapping SGs + +From: Roi Dayan + +commit c6c95ef4cec680f7a10aa425a9970744b35b6489 upstream. + +We always unmap SGs with the same direction instead of unmapping +with the direction the mapping was done, fix that. + +Fixes: 9a8b08fad2ef ("IB/iser: Generalize iser_unmap_task_data and [...]") +Signed-off-by: Roi Dayan +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/ulp/iser/iscsi_iser.h | 4 +++- + drivers/infiniband/ulp/iser/iser_initiator.c | 12 ++++++++---- + drivers/infiniband/ulp/iser/iser_memory.c | 9 ++++++--- + 3 files changed, 17 insertions(+), 8 deletions(-) + +--- a/drivers/infiniband/ulp/iser/iscsi_iser.h ++++ b/drivers/infiniband/ulp/iser/iscsi_iser.h +@@ -654,7 +654,9 @@ int iser_dma_map_task_data(struct iscsi_ + enum dma_data_direction dma_dir); + + void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task, +- struct iser_data_buf *data); ++ struct iser_data_buf *data, ++ enum dma_data_direction dir); ++ + int iser_initialize_task_headers(struct iscsi_task *task, + struct iser_tx_desc *tx_desc); + int iser_alloc_rx_descriptors(struct iser_conn *iser_conn, +--- a/drivers/infiniband/ulp/iser/iser_initiator.c ++++ b/drivers/infiniband/ulp/iser/iser_initiator.c +@@ -710,19 +710,23 @@ void iser_task_rdma_finalize(struct iscs + device->iser_unreg_rdma_mem(iser_task, ISER_DIR_IN); + if (is_rdma_data_aligned) + iser_dma_unmap_task_data(iser_task, +- &iser_task->data[ISER_DIR_IN]); ++ &iser_task->data[ISER_DIR_IN], ++ DMA_FROM_DEVICE); + if (prot_count && is_rdma_prot_aligned) + iser_dma_unmap_task_data(iser_task, +- &iser_task->prot[ISER_DIR_IN]); ++ &iser_task->prot[ISER_DIR_IN], ++ DMA_FROM_DEVICE); + } + + if (iser_task->dir[ISER_DIR_OUT]) { + device->iser_unreg_rdma_mem(iser_task, ISER_DIR_OUT); + if (is_rdma_data_aligned) + iser_dma_unmap_task_data(iser_task, +- &iser_task->data[ISER_DIR_OUT]); ++ &iser_task->data[ISER_DIR_OUT], ++ DMA_TO_DEVICE); + if (prot_count && is_rdma_prot_aligned) + iser_dma_unmap_task_data(iser_task, +- &iser_task->prot[ISER_DIR_OUT]); ++ &iser_task->prot[ISER_DIR_OUT], ++ DMA_TO_DEVICE); + } + } +--- a/drivers/infiniband/ulp/iser/iser_memory.c ++++ b/drivers/infiniband/ulp/iser/iser_memory.c +@@ -332,12 +332,13 @@ int iser_dma_map_task_data(struct iscsi_ + } + + void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task, +- struct iser_data_buf *data) ++ struct iser_data_buf *data, ++ enum dma_data_direction dir) + { + struct ib_device *dev; + + dev = iser_task->iser_conn->ib_conn.device->ib_device; +- ib_dma_unmap_sg(dev, data->buf, data->size, DMA_FROM_DEVICE); ++ ib_dma_unmap_sg(dev, data->buf, data->size, dir); + } + + static int fall_to_bounce_buf(struct iscsi_iser_task *iser_task, +@@ -357,7 +358,9 @@ static int fall_to_bounce_buf(struct isc + iser_data_buf_dump(mem, ibdev); + + /* unmap the command data before accessing it */ +- iser_dma_unmap_task_data(iser_task, mem); ++ iser_dma_unmap_task_data(iser_task, mem, ++ (cmd_dir == ISER_DIR_OUT) ? ++ DMA_TO_DEVICE : DMA_FROM_DEVICE); + + /* allocate copy buf, if we are writing, copy the */ + /* unaligned scatterlist, dma map the copy */ diff --git a/queue-3.19/ib-mlx4-fix-memory-leak-in-__mlx4_ib_modify_qp.patch b/queue-3.19/ib-mlx4-fix-memory-leak-in-__mlx4_ib_modify_qp.patch new file mode 100644 index 00000000000..e3460edaeb8 --- /dev/null +++ b/queue-3.19/ib-mlx4-fix-memory-leak-in-__mlx4_ib_modify_qp.patch @@ -0,0 +1,36 @@ +From bede98e781747623ae170667694a71ef19c6ba7f Mon Sep 17 00:00:00 2001 +From: Majd Dibbiny +Date: Thu, 29 Jan 2015 10:41:41 +0200 +Subject: IB/mlx4: Fix memory leak in __mlx4_ib_modify_qp + +From: Majd Dibbiny + +commit bede98e781747623ae170667694a71ef19c6ba7f upstream. + +In case handle_eth_ud_smac_index fails, we need to free the allocated resources. + +Fixes: 2f5bb473681b ("mlx4: Add ref counting to port MAC table for RoCE") +Signed-off-by: Majd Dibbiny +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/qp.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/mlx4/qp.c ++++ b/drivers/infiniband/hw/mlx4/qp.c +@@ -1674,8 +1674,10 @@ static int __mlx4_ib_modify_qp(struct ib + qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI || + qp->mlx4_ib_qp_type == MLX4_IB_QPT_TUN_GSI) { + err = handle_eth_ud_smac_index(dev, qp, (u8 *)attr->smac, context); +- if (err) +- return -EINVAL; ++ if (err) { ++ err = -EINVAL; ++ goto out; ++ } + if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI) + dev->qp1_proxy[qp->port - 1] = qp; + } diff --git a/queue-3.19/ib-mlx4-fix-wrong-usage-of-ipv4-protocol-for-multicast-attach-detach.patch b/queue-3.19/ib-mlx4-fix-wrong-usage-of-ipv4-protocol-for-multicast-attach-detach.patch new file mode 100644 index 00000000000..0999b367cec --- /dev/null +++ b/queue-3.19/ib-mlx4-fix-wrong-usage-of-ipv4-protocol-for-multicast-attach-detach.patch @@ -0,0 +1,56 @@ +From e9a7faf11af94957e5107b40af46c2e329541510 Mon Sep 17 00:00:00 2001 +From: Or Gerlitz +Date: Wed, 17 Dec 2014 16:17:34 +0200 +Subject: IB/mlx4: Fix wrong usage of IPv4 protocol for multicast attach/detach + +From: Or Gerlitz + +commit e9a7faf11af94957e5107b40af46c2e329541510 upstream. + +The MLX4_PROT_IB_IPV4 protocol should only be used with RoCEv2 and such. +Removing this wrong usage allows to run multicast applications over RoCE. + +Fixes: d487ee77740c ("IB/mlx4: Use IBoE (RoCE) IP based GIDs in the port GID table") +Reported-by: Carol Soto +Signed-off-by: Or Gerlitz +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx4/main.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/infiniband/hw/mlx4/main.c ++++ b/drivers/infiniband/hw/mlx4/main.c +@@ -1222,8 +1222,7 @@ static int mlx4_ib_mcg_attach(struct ib_ + struct mlx4_ib_qp *mqp = to_mqp(ibqp); + u64 reg_id; + struct mlx4_ib_steering *ib_steering = NULL; +- enum mlx4_protocol prot = (gid->raw[1] == 0x0e) ? +- MLX4_PROT_IB_IPV4 : MLX4_PROT_IB_IPV6; ++ enum mlx4_protocol prot = MLX4_PROT_IB_IPV6; + + if (mdev->dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) { +@@ -1236,8 +1235,10 @@ static int mlx4_ib_mcg_attach(struct ib_ + !!(mqp->flags & + MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK), + prot, ®_id); +- if (err) ++ if (err) { ++ pr_err("multicast attach op failed, err %d\n", err); + goto err_malloc; ++ } + + err = add_gid_entry(ibqp, gid); + if (err) +@@ -1285,8 +1286,7 @@ static int mlx4_ib_mcg_detach(struct ib_ + struct net_device *ndev; + struct mlx4_ib_gid_entry *ge; + u64 reg_id = 0; +- enum mlx4_protocol prot = (gid->raw[1] == 0x0e) ? +- MLX4_PROT_IB_IPV4 : MLX4_PROT_IB_IPV6; ++ enum mlx4_protocol prot = MLX4_PROT_IB_IPV6; + + if (mdev->dev->caps.steering_mode == + MLX4_STEERING_MODE_DEVICE_MANAGED) { diff --git a/queue-3.19/ib-mlx5-fix-error-code-in-get_port_caps.patch b/queue-3.19/ib-mlx5-fix-error-code-in-get_port_caps.patch new file mode 100644 index 00000000000..555bb25cf21 --- /dev/null +++ b/queue-3.19/ib-mlx5-fix-error-code-in-get_port_caps.patch @@ -0,0 +1,32 @@ +From f614fc15ae39ceb531586e3969f2b99fd23182a0 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 12 Jan 2015 11:56:58 +0300 +Subject: IB/mlx5: Fix error code in get_port_caps() + +From: Dan Carpenter + +commit f614fc15ae39ceb531586e3969f2b99fd23182a0 upstream. + +The current code returns success when kmalloc() fails. It should +return an error code, -ENOMEM. + +Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") +Signed-off-by: Dan Carpenter +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -997,7 +997,7 @@ static int get_port_caps(struct mlx5_ib_ + struct ib_device_attr *dprops = NULL; + struct ib_port_attr *pprops = NULL; + struct mlx5_general_caps *gen; +- int err = 0; ++ int err = -ENOMEM; + int port; + + gen = &dev->mdev->caps.gen; diff --git a/queue-3.19/ib-qib-do-not-write-eeprom.patch b/queue-3.19/ib-qib-do-not-write-eeprom.patch new file mode 100644 index 00000000000..96b890e4b1d --- /dev/null +++ b/queue-3.19/ib-qib-do-not-write-eeprom.patch @@ -0,0 +1,340 @@ +From 18c0b82a3e4501511b08d0e8676fb08ac08734a3 Mon Sep 17 00:00:00 2001 +From: Mitko Haralanov +Date: Fri, 16 Jan 2015 08:55:27 -0500 +Subject: IB/qib: Do not write EEPROM + +From: Mitko Haralanov + +commit 18c0b82a3e4501511b08d0e8676fb08ac08734a3 upstream. + +This changeset removes all the code that allows the driver to write to +the EEPROM and update the recorded error counters and power on hours. + +These two stats are unused and writing them exposes a timing risk +which could leave the EEPROM in a bad state preventing further normal +operation of the HCA. + +Reviewed-by: Mike Marciniszyn +Signed-off-by: Mitko Haralanov +Signed-off-by: Mike Marciniszyn +Signed-off-by: Roland Dreier +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/qib/qib.h | 9 - + drivers/infiniband/hw/qib/qib_eeprom.c | 181 -------------------------------- + drivers/infiniband/hw/qib/qib_iba6120.c | 2 + drivers/infiniband/hw/qib/qib_iba7220.c | 2 + drivers/infiniband/hw/qib/qib_iba7322.c | 2 + drivers/infiniband/hw/qib/qib_init.c | 1 + drivers/infiniband/hw/qib/qib_sysfs.c | 24 ---- + 7 files changed, 1 insertion(+), 220 deletions(-) + +--- a/drivers/infiniband/hw/qib/qib.h ++++ b/drivers/infiniband/hw/qib/qib.h +@@ -1082,12 +1082,6 @@ struct qib_devdata { + /* control high-level access to EEPROM */ + struct mutex eep_lock; + uint64_t traffic_wds; +- /* active time is kept in seconds, but logged in hours */ +- atomic_t active_time; +- /* Below are nominal shadow of EEPROM, new since last EEPROM update */ +- uint8_t eep_st_errs[QIB_EEP_LOG_CNT]; +- uint8_t eep_st_new_errs[QIB_EEP_LOG_CNT]; +- uint16_t eep_hrs; + /* + * masks for which bits of errs, hwerrs that cause + * each of the counters to increment. +@@ -1309,8 +1303,7 @@ int qib_twsi_blk_rd(struct qib_devdata * + int qib_twsi_blk_wr(struct qib_devdata *dd, int dev, int addr, + const void *buffer, int len); + void qib_get_eeprom_info(struct qib_devdata *); +-int qib_update_eeprom_log(struct qib_devdata *dd); +-void qib_inc_eeprom_err(struct qib_devdata *dd, u32 eidx, u32 incr); ++#define qib_inc_eeprom_err(dd, eidx, incr) + void qib_dump_lookup_output_queue(struct qib_devdata *); + void qib_force_pio_avail_update(struct qib_devdata *); + void qib_clear_symerror_on_linkup(unsigned long opaque); +--- a/drivers/infiniband/hw/qib/qib_eeprom.c ++++ b/drivers/infiniband/hw/qib/qib_eeprom.c +@@ -267,190 +267,9 @@ void qib_get_eeprom_info(struct qib_devd + "Board SN %s did not pass functional test: %s\n", + dd->serial, ifp->if_comment); + +- memcpy(&dd->eep_st_errs, &ifp->if_errcntp, QIB_EEP_LOG_CNT); +- /* +- * Power-on (actually "active") hours are kept as little-endian value +- * in EEPROM, but as seconds in a (possibly as small as 24-bit) +- * atomic_t while running. +- */ +- atomic_set(&dd->active_time, 0); +- dd->eep_hrs = ifp->if_powerhour[0] | (ifp->if_powerhour[1] << 8); +- + done: + vfree(buf); + + bail:; + } + +-/** +- * qib_update_eeprom_log - copy active-time and error counters to eeprom +- * @dd: the qlogic_ib device +- * +- * Although the time is kept as seconds in the qib_devdata struct, it is +- * rounded to hours for re-write, as we have only 16 bits in EEPROM. +- * First-cut code reads whole (expected) struct qib_flash, modifies, +- * re-writes. Future direction: read/write only what we need, assuming +- * that the EEPROM had to have been "good enough" for driver init, and +- * if not, we aren't making it worse. +- * +- */ +-int qib_update_eeprom_log(struct qib_devdata *dd) +-{ +- void *buf; +- struct qib_flash *ifp; +- int len, hi_water; +- uint32_t new_time, new_hrs; +- u8 csum; +- int ret, idx; +- unsigned long flags; +- +- /* first, check if we actually need to do anything. */ +- ret = 0; +- for (idx = 0; idx < QIB_EEP_LOG_CNT; ++idx) { +- if (dd->eep_st_new_errs[idx]) { +- ret = 1; +- break; +- } +- } +- new_time = atomic_read(&dd->active_time); +- +- if (ret == 0 && new_time < 3600) +- goto bail; +- +- /* +- * The quick-check above determined that there is something worthy +- * of logging, so get current contents and do a more detailed idea. +- * read full flash, not just currently used part, since it may have +- * been written with a newer definition +- */ +- len = sizeof(struct qib_flash); +- buf = vmalloc(len); +- ret = 1; +- if (!buf) { +- qib_dev_err(dd, +- "Couldn't allocate memory to read %u bytes from eeprom for logging\n", +- len); +- goto bail; +- } +- +- /* Grab semaphore and read current EEPROM. If we get an +- * error, let go, but if not, keep it until we finish write. +- */ +- ret = mutex_lock_interruptible(&dd->eep_lock); +- if (ret) { +- qib_dev_err(dd, "Unable to acquire EEPROM for logging\n"); +- goto free_bail; +- } +- ret = qib_twsi_blk_rd(dd, dd->twsi_eeprom_dev, 0, buf, len); +- if (ret) { +- mutex_unlock(&dd->eep_lock); +- qib_dev_err(dd, "Unable read EEPROM for logging\n"); +- goto free_bail; +- } +- ifp = (struct qib_flash *)buf; +- +- csum = flash_csum(ifp, 0); +- if (csum != ifp->if_csum) { +- mutex_unlock(&dd->eep_lock); +- qib_dev_err(dd, "EEPROM cks err (0x%02X, S/B 0x%02X)\n", +- csum, ifp->if_csum); +- ret = 1; +- goto free_bail; +- } +- hi_water = 0; +- spin_lock_irqsave(&dd->eep_st_lock, flags); +- for (idx = 0; idx < QIB_EEP_LOG_CNT; ++idx) { +- int new_val = dd->eep_st_new_errs[idx]; +- if (new_val) { +- /* +- * If we have seen any errors, add to EEPROM values +- * We need to saturate at 0xFF (255) and we also +- * would need to adjust the checksum if we were +- * trying to minimize EEPROM traffic +- * Note that we add to actual current count in EEPROM, +- * in case it was altered while we were running. +- */ +- new_val += ifp->if_errcntp[idx]; +- if (new_val > 0xFF) +- new_val = 0xFF; +- if (ifp->if_errcntp[idx] != new_val) { +- ifp->if_errcntp[idx] = new_val; +- hi_water = offsetof(struct qib_flash, +- if_errcntp) + idx; +- } +- /* +- * update our shadow (used to minimize EEPROM +- * traffic), to match what we are about to write. +- */ +- dd->eep_st_errs[idx] = new_val; +- dd->eep_st_new_errs[idx] = 0; +- } +- } +- /* +- * Now update active-time. We would like to round to the nearest hour +- * but unless atomic_t are sure to be proper signed ints we cannot, +- * because we need to account for what we "transfer" to EEPROM and +- * if we log an hour at 31 minutes, then we would need to set +- * active_time to -29 to accurately count the _next_ hour. +- */ +- if (new_time >= 3600) { +- new_hrs = new_time / 3600; +- atomic_sub((new_hrs * 3600), &dd->active_time); +- new_hrs += dd->eep_hrs; +- if (new_hrs > 0xFFFF) +- new_hrs = 0xFFFF; +- dd->eep_hrs = new_hrs; +- if ((new_hrs & 0xFF) != ifp->if_powerhour[0]) { +- ifp->if_powerhour[0] = new_hrs & 0xFF; +- hi_water = offsetof(struct qib_flash, if_powerhour); +- } +- if ((new_hrs >> 8) != ifp->if_powerhour[1]) { +- ifp->if_powerhour[1] = new_hrs >> 8; +- hi_water = offsetof(struct qib_flash, if_powerhour) + 1; +- } +- } +- /* +- * There is a tiny possibility that we could somehow fail to write +- * the EEPROM after updating our shadows, but problems from holding +- * the spinlock too long are a much bigger issue. +- */ +- spin_unlock_irqrestore(&dd->eep_st_lock, flags); +- if (hi_water) { +- /* we made some change to the data, uopdate cksum and write */ +- csum = flash_csum(ifp, 1); +- ret = eeprom_write_with_enable(dd, 0, buf, hi_water + 1); +- } +- mutex_unlock(&dd->eep_lock); +- if (ret) +- qib_dev_err(dd, "Failed updating EEPROM\n"); +- +-free_bail: +- vfree(buf); +-bail: +- return ret; +-} +- +-/** +- * qib_inc_eeprom_err - increment one of the four error counters +- * that are logged to EEPROM. +- * @dd: the qlogic_ib device +- * @eidx: 0..3, the counter to increment +- * @incr: how much to add +- * +- * Each counter is 8-bits, and saturates at 255 (0xFF). They +- * are copied to the EEPROM (aka flash) whenever qib_update_eeprom_log() +- * is called, but it can only be called in a context that allows sleep. +- * This function can be called even at interrupt level. +- */ +-void qib_inc_eeprom_err(struct qib_devdata *dd, u32 eidx, u32 incr) +-{ +- uint new_val; +- unsigned long flags; +- +- spin_lock_irqsave(&dd->eep_st_lock, flags); +- new_val = dd->eep_st_new_errs[eidx] + incr; +- if (new_val > 255) +- new_val = 255; +- dd->eep_st_new_errs[eidx] = new_val; +- spin_unlock_irqrestore(&dd->eep_st_lock, flags); +-} +--- a/drivers/infiniband/hw/qib/qib_iba6120.c ++++ b/drivers/infiniband/hw/qib/qib_iba6120.c +@@ -2681,8 +2681,6 @@ static void qib_get_6120_faststats(unsig + spin_lock_irqsave(&dd->eep_st_lock, flags); + traffic_wds -= dd->traffic_wds; + dd->traffic_wds += traffic_wds; +- if (traffic_wds >= QIB_TRAFFIC_ACTIVE_THRESHOLD) +- atomic_add(5, &dd->active_time); /* S/B #define */ + spin_unlock_irqrestore(&dd->eep_st_lock, flags); + + qib_chk_6120_errormask(dd); +--- a/drivers/infiniband/hw/qib/qib_iba7220.c ++++ b/drivers/infiniband/hw/qib/qib_iba7220.c +@@ -3297,8 +3297,6 @@ static void qib_get_7220_faststats(unsig + spin_lock_irqsave(&dd->eep_st_lock, flags); + traffic_wds -= dd->traffic_wds; + dd->traffic_wds += traffic_wds; +- if (traffic_wds >= QIB_TRAFFIC_ACTIVE_THRESHOLD) +- atomic_add(5, &dd->active_time); /* S/B #define */ + spin_unlock_irqrestore(&dd->eep_st_lock, flags); + done: + mod_timer(&dd->stats_timer, jiffies + HZ * ACTIVITY_TIMER); +--- a/drivers/infiniband/hw/qib/qib_iba7322.c ++++ b/drivers/infiniband/hw/qib/qib_iba7322.c +@@ -5178,8 +5178,6 @@ static void qib_get_7322_faststats(unsig + spin_lock_irqsave(&ppd->dd->eep_st_lock, flags); + traffic_wds -= ppd->dd->traffic_wds; + ppd->dd->traffic_wds += traffic_wds; +- if (traffic_wds >= QIB_TRAFFIC_ACTIVE_THRESHOLD) +- atomic_add(ACTIVITY_TIMER, &ppd->dd->active_time); + spin_unlock_irqrestore(&ppd->dd->eep_st_lock, flags); + if (ppd->cpspec->qdr_dfe_on && (ppd->link_speed_active & + QIB_IB_QDR) && +--- a/drivers/infiniband/hw/qib/qib_init.c ++++ b/drivers/infiniband/hw/qib/qib_init.c +@@ -931,7 +931,6 @@ static void qib_shutdown_device(struct q + qib_free_pportdata(ppd); + } + +- qib_update_eeprom_log(dd); + } + + /** +--- a/drivers/infiniband/hw/qib/qib_sysfs.c ++++ b/drivers/infiniband/hw/qib/qib_sysfs.c +@@ -611,28 +611,6 @@ bail: + return ret < 0 ? ret : count; + } + +-static ssize_t show_logged_errs(struct device *device, +- struct device_attribute *attr, char *buf) +-{ +- struct qib_ibdev *dev = +- container_of(device, struct qib_ibdev, ibdev.dev); +- struct qib_devdata *dd = dd_from_dev(dev); +- int idx, count; +- +- /* force consistency with actual EEPROM */ +- if (qib_update_eeprom_log(dd) != 0) +- return -ENXIO; +- +- count = 0; +- for (idx = 0; idx < QIB_EEP_LOG_CNT; ++idx) { +- count += scnprintf(buf + count, PAGE_SIZE - count, "%d%c", +- dd->eep_st_errs[idx], +- idx == (QIB_EEP_LOG_CNT - 1) ? '\n' : ' '); +- } +- +- return count; +-} +- + /* + * Dump tempsense regs. in decimal, to ease shell-scripts. + */ +@@ -679,7 +657,6 @@ static DEVICE_ATTR(nctxts, S_IRUGO, show + static DEVICE_ATTR(nfreectxts, S_IRUGO, show_nfreectxts, NULL); + static DEVICE_ATTR(serial, S_IRUGO, show_serial, NULL); + static DEVICE_ATTR(boardversion, S_IRUGO, show_boardversion, NULL); +-static DEVICE_ATTR(logged_errors, S_IRUGO, show_logged_errs, NULL); + static DEVICE_ATTR(tempsense, S_IRUGO, show_tempsense, NULL); + static DEVICE_ATTR(localbus_info, S_IRUGO, show_localbus_info, NULL); + static DEVICE_ATTR(chip_reset, S_IWUSR, NULL, store_chip_reset); +@@ -693,7 +670,6 @@ static struct device_attribute *qib_attr + &dev_attr_nfreectxts, + &dev_attr_serial, + &dev_attr_boardversion, +- &dev_attr_logged_errors, + &dev_attr_tempsense, + &dev_attr_localbus_info, + &dev_attr_chip_reset, diff --git a/queue-3.19/locking-rtmutex-avoid-a-null-pointer-dereference-on-deadlock.patch b/queue-3.19/locking-rtmutex-avoid-a-null-pointer-dereference-on-deadlock.patch new file mode 100644 index 00000000000..b2d9ea6ad7d --- /dev/null +++ b/queue-3.19/locking-rtmutex-avoid-a-null-pointer-dereference-on-deadlock.patch @@ -0,0 +1,44 @@ +From 8d1e5a1a1ccf5ae9d8a5a0ee7960202ccb0c5429 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 17 Feb 2015 16:43:43 +0100 +Subject: locking/rtmutex: Avoid a NULL pointer dereference on deadlock + +From: Sebastian Andrzej Siewior + +commit 8d1e5a1a1ccf5ae9d8a5a0ee7960202ccb0c5429 upstream. + +With task_blocks_on_rt_mutex() returning early -EDEADLK we never +add the waiter to the waitqueue. Later, we try to remove it via +remove_waiter() and go boom in rt_mutex_top_waiter() because +rb_entry() gives a NULL pointer. + +( Tested on v3.18-RT where rtmutex is used for regular mutex and I + tried to get one twice in a row. ) + +Not sure when this started but I guess 397335f004f4 ("rtmutex: Fix +deadlock detector for real") or commit 3d5c9340d194 ("rtmutex: +Handle deadlock detection smarter"). + +Signed-off-by: Sebastian Andrzej Siewior +Acked-by: Peter Zijlstra +Cc: Thomas Gleixner +Link: http://lkml.kernel.org/r/1424187823-19600-1-git-send-email-bigeasy@linutronix.de +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/locking/rtmutex.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/locking/rtmutex.c ++++ b/kernel/locking/rtmutex.c +@@ -1193,7 +1193,8 @@ rt_mutex_slowlock(struct rt_mutex *lock, + set_current_state(TASK_RUNNING); + + if (unlikely(ret)) { +- remove_waiter(lock, &waiter); ++ if (rt_mutex_has_waiters(lock)) ++ remove_waiter(lock, &waiter); + rt_mutex_handle_deadlock(ret, chwalk, &waiter); + } + diff --git a/queue-3.19/series b/queue-3.19/series index be795529eca..5ae9472ddba 100644 --- a/queue-3.19/series +++ b/queue-3.19/series @@ -113,3 +113,14 @@ alsa-hda-controller-code-do-not-export-static-functions.patch alsa-hda-disable-runtime-pm-for-panther-point-again.patch alsa-oxfw-fix-a-condition-and-return-code-in-start_stream.patch alsa-hda-one-more-dell-macine-needs-dell1_mic_no_presence-quirk.patch +locking-rtmutex-avoid-a-null-pointer-dereference-on-deadlock.patch +sg-fix-read-error-reporting.patch +ib-qib-do-not-write-eeprom.patch +ib-iser-fix-memory-regions-possible-leak.patch +ib-iser-use-correct-dma-direction-when-unmapping-sgs.patch +ib-mlx5-fix-error-code-in-get_port_caps.patch +ib-mlx4-fix-memory-leak-in-__mlx4_ib_modify_qp.patch +ib-mlx4-fix-wrong-usage-of-ipv4-protocol-for-multicast-attach-detach.patch +ib-core-fix-deadlock-on-uverbs-modify_qp-error-flow.patch +ib-core-properly-handle-registration-of-on-demand-paging-mrs-after-dereg.patch +ib-core-when-marshaling-ucma-path-from-user-space-clear-unused-fields.patch diff --git a/queue-3.19/sg-fix-read-error-reporting.patch b/queue-3.19/sg-fix-read-error-reporting.patch new file mode 100644 index 00000000000..b49ad6f402b --- /dev/null +++ b/queue-3.19/sg-fix-read-error-reporting.patch @@ -0,0 +1,43 @@ +From 3b524a683af8991b4eab4182b947c65f0ce1421b Mon Sep 17 00:00:00 2001 +From: Tony Battersby +Date: Wed, 11 Feb 2015 11:32:06 -0500 +Subject: sg: fix read() error reporting + +From: Tony Battersby + +commit 3b524a683af8991b4eab4182b947c65f0ce1421b upstream. + +Fix SCSI generic read() incorrectly returning success after detecting an +error. + +Signed-off-by: Tony Battersby +Acked-by: Douglas Gilbert +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/sg.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -546,7 +546,7 @@ static ssize_t + sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp) + { + sg_io_hdr_t *hp = &srp->header; +- int err = 0; ++ int err = 0, err2; + int len; + + if (count < SZ_SG_IO_HDR) { +@@ -575,8 +575,8 @@ sg_new_read(Sg_fd * sfp, char __user *bu + goto err_out; + } + err_out: +- err = sg_finish_rem_req(srp); +- return (0 == err) ? count : err; ++ err2 = sg_finish_rem_req(srp); ++ return err ? : err2 ? : count; + } + + static ssize_t