--- /dev/null
+From 0fb8bcf022f19a375d7c4bd79ac513da8ae6d78b Mon Sep 17 00:00:00 2001
+From: Moshe Lazer <moshel@mellanox.com>
+Date: Thu, 5 Feb 2015 13:53:52 +0200
+Subject: [PATCH] IB/core: Fix deadlock on uverbs modify_qp error flow
+
+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 <moshel@mellanox.com>
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+---
+ drivers/infiniband/core/uverbs_cmd.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
+index b7943ff..6c52e72 100644
+--- 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_uverbs_file *file,
+ 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);
+
+--
+1.8.3.1
+
--- /dev/null
+From c1bd6cde8efda081af9d4f1fa4105e114b9b5cf5 Mon Sep 17 00:00:00 2001
+From: Moni Shoua <monis@mellanox.com>
+Date: Wed, 19 Nov 2014 11:28:18 +0200
+Subject: [PATCH] IB/core: Do not resolve VLAN if already resolved
+
+For RoCE, resolution of layer 2 address attributes forces no VLAN if
+link-local GIDs are used. This patch allows applications to choose
+the VLAN ID for link-local based RoCE GIDs by setting IB_QP_VID in
+their QP attribute mask, and prevents the core from overriding this
+choice.
+
+Cc: Ursula Braun <ursula.braun@de.ibm.com>
+Signed-off-by: Moni Shoua <monis@mellanox.com>
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+---
+ drivers/infiniband/core/verbs.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
+index c2b89cc..f93eb8d 100644
+--- a/drivers/infiniband/core/verbs.c
++++ b/drivers/infiniband/core/verbs.c
+@@ -879,7 +879,8 @@ int ib_resolve_eth_l2_attrs(struct ib_qp *qp,
+ if (rdma_link_local_addr((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw)) {
+ rdma_get_ll_mac((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw, qp_attr->ah_attr.dmac);
+ rdma_get_ll_mac((struct in6_addr *)sgid.raw, qp_attr->smac);
+- qp_attr->vlan_id = rdma_get_vlan_id(&sgid);
++ if (!(*qp_attr_mask & IB_QP_VID))
++ qp_attr->vlan_id = rdma_get_vlan_id(&sgid);
+ } else {
+ ret = rdma_addr_find_dmac_by_grh(&sgid, &qp_attr->ah_attr.grh.dgid,
+ qp_attr->ah_attr.dmac, &qp_attr->vlan_id);
+--
+1.8.3.1
+
--- /dev/null
+From 514f3ddffe7c366af7921fdddaae3811e3efce03 Mon Sep 17 00:00:00 2001
+From: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Date: Wed, 19 Nov 2014 11:08:58 +0200
+Subject: [PATCH] IB/core: Fix mgid key handling in SA agent multicast
+ data-base
+
+Applications can request that the SM assign an MGID by passing a mcast
+member request containing MGID = 0. When the SM responds by sending
+the allocated MGID, this MGID replaces the 0-MGID in the multicast group.
+
+However, the MGID field in the group is also the key field in the IB
+core multicast code rbtree containing the multicast groups for the
+port.
+
+Since this is a key field, correct handling requires that the group
+entry be deleted from the rbtree and then re-inserted with the new
+key, so that the table structure is properly maintained.
+
+The current code does not do this correctly. Correct operation
+requires that if the key-field gid has changed at all, it should be
+deleted and re-inserted.
+
+Note that when inserting, if the new MGID is zero (not the case here
+but the code should handle this correctly), we allow duplicate entries
+for 0-MGIDs.
+
+Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Acked-by: Sean Hefty <sean.hefty@intel.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+---
+ drivers/infiniband/core/multicast.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c
+index d2360a8..fa17b55 100644
+--- a/drivers/infiniband/core/multicast.c
++++ b/drivers/infiniband/core/multicast.c
+@@ -525,17 +525,22 @@ static void join_handler(int status, struct ib_sa_mcmember_rec *rec,
+ if (status)
+ process_join_error(group, status);
+ else {
++ int mgids_changed, is_mgid0;
+ ib_find_pkey(group->port->dev->device, group->port->port_num,
+ be16_to_cpu(rec->pkey), &pkey_index);
+
+ spin_lock_irq(&group->port->lock);
+- group->rec = *rec;
+ if (group->state == MCAST_BUSY &&
+ group->pkey_index == MCAST_INVALID_PKEY_INDEX)
+ group->pkey_index = pkey_index;
+- if (!memcmp(&mgid0, &group->rec.mgid, sizeof mgid0)) {
++ mgids_changed = memcmp(&rec->mgid, &group->rec.mgid,
++ sizeof(group->rec.mgid));
++ group->rec = *rec;
++ if (mgids_changed) {
+ rb_erase(&group->node, &group->port->table);
+- mcast_insert(group->port, group, 1);
++ is_mgid0 = !memcmp(&mgid0, &group->rec.mgid,
++ sizeof(mgid0));
++ mcast_insert(group->port, group, is_mgid0);
+ }
+ spin_unlock_irq(&group->port->lock);
+ }
+--
+1.8.3.1
+
--- /dev/null
+From 346f98b41b76281bd0b748fb86bc1953c9fd9fe2 Mon Sep 17 00:00:00 2001
+From: Or Kehati <ork@mellanox.com>
+Date: Wed, 29 Oct 2014 16:32:04 +0200
+Subject: [PATCH] IB/addr: Improve address resolution callback scheduling
+
+Address resolution always does a context switch to a work-queue to
+deliver the address resolution event. When the IP address is already
+cached in the system ARP table, we're going through the following:
+chain:
+
+ rdma_resolve_ip --> addr_resolve (cache hit) -->
+
+which ends up with:
+
+ queue_req --> set_timeout (now) --> mod_delayed_work(,, delay=1)
+
+We actually do realize that the timeout should be zero, but the code
+forces it to a minimum of one jiffie.
+
+Using one jiffie as the minimum delay value results in sub-optimal
+scheduling of executing this work item by the workqueue, which on the
+below testbed costs about 3-4ms out of 12ms total time.
+
+To fix that, we let the minimum delay to be zero. Note that the
+connect step times change too, as there are address resolution calls
+from that flow.
+
+The results were taken from running both client and server on the
+same node, over mlx4 RoCE port.
+
+before -->
+step total ms max ms min us us / conn
+create id : 0.01 0.01 6.00 6.00
+resolve addr : 4.02 4.01 4013.00 4016.00
+resolve route: 0.18 0.18 182.00 183.00
+create qp : 1.15 1.15 1150.00 1150.00
+connect : 6.73 6.73 6730.00 6731.00
+disconnect : 0.55 0.55 549.00 550.00
+destroy : 0.01 0.01 9.00 9.00
+
+after -->
+step total ms max ms min us us / conn
+create id : 0.01 0.01 6.00 6.00
+resolve addr : 0.05 0.05 49.00 52.00
+resolve route: 0.21 0.21 207.00 208.00
+create qp : 1.10 1.10 1104.00 1104.00
+connect : 1.22 1.22 1220.00 1221.00
+disconnect : 0.71 0.71 713.00 713.00
+destroy : 0.01 0.01 9.00 9.00
+
+Signed-off-by: Or Kehati <ork@mellanox.com>
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Acked-by: Sean Hefty <sean.hefty@intel.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+---
+ drivers/infiniband/core/addr.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
+index 8172d37..f80da50 100644
+--- a/drivers/infiniband/core/addr.c
++++ b/drivers/infiniband/core/addr.c
+@@ -176,8 +176,8 @@ static void set_timeout(unsigned long time)
+ unsigned long delay;
+
+ delay = time - jiffies;
+- if ((long)delay <= 0)
+- delay = 1;
++ if ((long)delay < 0)
++ delay = 0;
+
+ mod_delayed_work(addr_wq, &work, delay);
+ }
+--
+1.8.3.1
+
--- /dev/null
+From 66578b0b2f69659f00b6169e6fe7377c4b100d18 Mon Sep 17 00:00:00 2001
+From: Yann Droneaud <ydroneaud@opteya.com>
+Date: Mon, 13 Apr 2015 14:56:23 +0200
+Subject: [PATCH] IB/core: don't disallow registering region starting at 0x0
+
+In a call to ib_umem_get(), if address is 0x0 and size is
+already page aligned, check added in commit 8494057ab5e4
+("IB/uverbs: Prevent integer overflow in ib_umem_get address
+arithmetic") will refuse to register a memory region that
+could otherwise be valid (provided vm.mmap_min_addr sysctl
+and mmap_low_allowed SELinux knobs allow userspace to map
+something at address 0x0).
+
+This patch allows back such registration: ib_umem_get()
+should probably don't care of the base address provided it
+can be pinned with get_user_pages().
+
+There's two possible overflows, in (addr + size) and in
+PAGE_ALIGN(addr + size), this patch keep ensuring none
+of them happen while allowing to pin memory at address
+0x0. Anyway, the case of size equal 0 is no more (partially)
+handled as 0-length memory region are disallowed by an
+earlier check.
+
+Link: http://mid.gmane.org/cover.1428929103.git.ydroneaud@opteya.com
+Cc: <stable@vger.kernel.org> # 8494057ab5e4 ("IB/uverbs: Prevent integer overflow in ib_umem_get address arithmetic")
+Cc: Shachar Raindel <raindel@mellanox.com>
+Cc: Jack Morgenstein <jackm@mellanox.com>
+Cc: Or Gerlitz <ogerlitz@mellanox.com>
+Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>
+Reviewed-by: Sagi Grimberg <sagig@mellanox.com>
+Reviewed-by: Haggai Eran <haggaie@mellanox.com>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+---
+ drivers/infiniband/core/umem.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
+index 9ac4068..38acb3c 100644
+--- a/drivers/infiniband/core/umem.c
++++ b/drivers/infiniband/core/umem.c
+@@ -106,8 +106,8 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
+ * If the combination of the addr and size requested for this memory
+ * region causes an integer overflow, return error.
+ */
+- if ((PAGE_ALIGN(addr + size) <= size) ||
+- (PAGE_ALIGN(addr + size) <= addr))
++ if (((addr + size) < addr) ||
++ PAGE_ALIGN(addr + size) < (addr + size))
+ return ERR_PTR(-EINVAL);
+
+ if (!can_do_mlock())
+--
+1.8.3.1
+
--- /dev/null
+From a233c4b54c882817ae9dd73384d5dd75d3e57498 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?S=C3=A9bastien=20Dugu=C3=A9?= <sebastien.dugue@atos.net>
+Date: Thu, 9 Apr 2015 11:13:41 +0200
+Subject: [PATCH] ib_uverbs: Fix pages leak when using XRC SRQs
+
+Hello,
+
+ When an application using XRCs abruptly terminates, the mmaped pages
+of the CQ buffers are leaked.
+
+ This comes from the fact that when resources are released in
+ib_uverbs_cleanup_ucontext(), we fail to release the CQs because their
+refcount is not 0.
+
+ When creating an XRC SRQ, we increment the associated CQ refcount.
+This refcount is only decremented when the SRQ is released.
+
+ Therefore we need to release the SRQs prior to the CQs to make sure
+that all references to the CQs are gone before trying to release these.
+
+Signed-off-by: Sebastien Dugue <sebastien.dugue@bull.net>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+---
+ drivers/infiniband/core/uverbs_main.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
+index 259dcc7..88cce9b 100644
+--- a/drivers/infiniband/core/uverbs_main.c
++++ b/drivers/infiniband/core/uverbs_main.c
+@@ -246,6 +246,17 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
+ kfree(uqp);
+ }
+
++ list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) {
++ struct ib_srq *srq = uobj->object;
++ struct ib_uevent_object *uevent =
++ container_of(uobj, struct ib_uevent_object, uobject);
++
++ idr_remove_uobj(&ib_uverbs_srq_idr, uobj);
++ ib_destroy_srq(srq);
++ ib_uverbs_release_uevent(file, uevent);
++ kfree(uevent);
++ }
++
+ list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) {
+ struct ib_cq *cq = uobj->object;
+ struct ib_uverbs_event_file *ev_file = cq->cq_context;
+@@ -258,17 +269,6 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
+ kfree(ucq);
+ }
+
+- list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) {
+- struct ib_srq *srq = uobj->object;
+- struct ib_uevent_object *uevent =
+- container_of(uobj, struct ib_uevent_object, uobject);
+-
+- idr_remove_uobj(&ib_uverbs_srq_idr, uobj);
+- ib_destroy_srq(srq);
+- ib_uverbs_release_uevent(file, uevent);
+- kfree(uevent);
+- }
+-
+ list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) {
+ struct ib_mr *mr = uobj->object;
+
+--
+1.8.3.1
+
--- /dev/null
+From 0d0f738f6a11856a704dcd8fd3a008b200f17625 Mon Sep 17 00:00:00 2001
+From: David Ahern <david.ahern@oracle.com>
+Date: Sun, 3 May 2015 09:48:26 -0400
+Subject: [PATCH] IB/core: Fix unaligned accesses
+
+Addresses the following kernel logs seen during boot of sparc systems:
+
+Kernel unaligned access at TPC[103bce50] cm_find_listen+0x34/0xf8 [ib_cm]
+Kernel unaligned access at TPC[103bce50] cm_find_listen+0x34/0xf8 [ib_cm]
+Kernel unaligned access at TPC[103bce50] cm_find_listen+0x34/0xf8 [ib_cm]
+Kernel unaligned access at TPC[103bce50] cm_find_listen+0x34/0xf8 [ib_cm]
+Kernel unaligned access at TPC[103bce50] cm_find_listen+0x34/0xf8 [ib_cm]
+
+Signed-off-by: David Ahern <david.ahern@oracle.com>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+---
+ drivers/infiniband/core/cm.c | 23 +++++++++++------------
+ drivers/infiniband/core/cm_msgs.h | 4 ++--
+ include/rdma/ib_cm.h | 7 ++++---
+ 3 files changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index e28a494..0c14191 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -437,39 +437,38 @@ static struct cm_id_private * cm_acquire_id(__be32 local_id, __be32 remote_id)
+ return cm_id_priv;
+ }
+
+-static void cm_mask_copy(u8 *dst, u8 *src, u8 *mask)
++static void cm_mask_copy(u32 *dst, const u32 *src, const u32 *mask)
+ {
+ int i;
+
+- for (i = 0; i < IB_CM_COMPARE_SIZE / sizeof(unsigned long); i++)
+- ((unsigned long *) dst)[i] = ((unsigned long *) src)[i] &
+- ((unsigned long *) mask)[i];
++ for (i = 0; i < IB_CM_COMPARE_SIZE; i++)
++ dst[i] = src[i] & mask[i];
+ }
+
+ static int cm_compare_data(struct ib_cm_compare_data *src_data,
+ struct ib_cm_compare_data *dst_data)
+ {
+- u8 src[IB_CM_COMPARE_SIZE];
+- u8 dst[IB_CM_COMPARE_SIZE];
++ u32 src[IB_CM_COMPARE_SIZE];
++ u32 dst[IB_CM_COMPARE_SIZE];
+
+ if (!src_data || !dst_data)
+ return 0;
+
+ cm_mask_copy(src, src_data->data, dst_data->mask);
+ cm_mask_copy(dst, dst_data->data, src_data->mask);
+- return memcmp(src, dst, IB_CM_COMPARE_SIZE);
++ return memcmp(src, dst, sizeof(src));
+ }
+
+-static int cm_compare_private_data(u8 *private_data,
++static int cm_compare_private_data(u32 *private_data,
+ struct ib_cm_compare_data *dst_data)
+ {
+- u8 src[IB_CM_COMPARE_SIZE];
++ u32 src[IB_CM_COMPARE_SIZE];
+
+ if (!dst_data)
+ return 0;
+
+ cm_mask_copy(src, private_data, dst_data->mask);
+- return memcmp(src, dst_data->data, IB_CM_COMPARE_SIZE);
++ return memcmp(src, dst_data->data, sizeof(src));
+ }
+
+ /*
+@@ -538,7 +537,7 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv)
+
+ static struct cm_id_private * cm_find_listen(struct ib_device *device,
+ __be64 service_id,
+- u8 *private_data)
++ u32 *private_data)
+ {
+ struct rb_node *node = cm.listen_service_table.rb_node;
+ struct cm_id_private *cm_id_priv;
+@@ -953,7 +952,7 @@ int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask,
+ cm_mask_copy(cm_id_priv->compare_data->data,
+ compare_data->data, compare_data->mask);
+ memcpy(cm_id_priv->compare_data->mask, compare_data->mask,
+- IB_CM_COMPARE_SIZE);
++ sizeof(compare_data->mask));
+ }
+
+ cm_id->state = IB_CM_LISTEN;
+diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h
+index be068f4..8b76f0e 100644
+--- a/drivers/infiniband/core/cm_msgs.h
++++ b/drivers/infiniband/core/cm_msgs.h
+@@ -103,7 +103,7 @@ struct cm_req_msg {
+ /* local ACK timeout:5, rsvd:3 */
+ u8 alt_offset139;
+
+- u8 private_data[IB_CM_REQ_PRIVATE_DATA_SIZE];
++ u32 private_data[IB_CM_REQ_PRIVATE_DATA_SIZE / sizeof(u32)];
+
+ } __attribute__ ((packed));
+
+@@ -801,7 +801,7 @@ struct cm_sidr_req_msg {
+ __be16 rsvd;
+ __be64 service_id;
+
+- u8 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE];
++ u32 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE / sizeof(u32)];
+ } __attribute__ ((packed));
+
+ struct cm_sidr_rep_msg {
+diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h
+index 0e3ff30..39ed2d2 100644
+--- a/include/rdma/ib_cm.h
++++ b/include/rdma/ib_cm.h
+@@ -105,7 +105,8 @@ enum ib_cm_data_size {
+ IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE = 216,
+ IB_CM_SIDR_REP_PRIVATE_DATA_SIZE = 136,
+ IB_CM_SIDR_REP_INFO_LENGTH = 72,
+- IB_CM_COMPARE_SIZE = 64
++ /* compare done u32 at a time */
++ IB_CM_COMPARE_SIZE = (64 / sizeof(u32))
+ };
+
+ struct ib_cm_id;
+@@ -337,8 +338,8 @@ void ib_destroy_cm_id(struct ib_cm_id *cm_id);
+ #define IB_SDP_SERVICE_ID_MASK cpu_to_be64(0xFFFFFFFFFFFF0000ULL)
+
+ struct ib_cm_compare_data {
+- u8 data[IB_CM_COMPARE_SIZE];
+- u8 mask[IB_CM_COMPARE_SIZE];
++ u32 data[IB_CM_COMPARE_SIZE];
++ u32 mask[IB_CM_COMPARE_SIZE];
+ };
+
+ /**
+--
+1.8.3.1
+