]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
RDMA/rvt: Do not use a kernel header in the ABI
authorJason Gunthorpe <jgg@mellanox.com>
Mon, 8 Jul 2019 15:17:48 +0000 (12:17 -0300)
committerJason Gunthorpe <jgg@mellanox.com>
Mon, 8 Jul 2019 16:00:29 +0000 (13:00 -0300)
rvt was using ib_sge as part of it's ABI, which is not allowed. Introduce
a new struct with the same layout and use it instead.

Fixes: dabac6e460ce ("IB/hfi1: Move receive work queue struct into uapi directory")
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/sw/rdmavt/qp.c
include/uapi/rdma/rvt-abi.h

index 11b4d3c1efd486e6f7d9c1311725af62911c1b12..0b0a241c57ff37e2897fc7a63dc3b45e525ba6fb 100644 (file)
@@ -1847,8 +1847,11 @@ int rvt_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr,
                        wqe = rvt_get_rwqe_ptr(&qp->r_rq, wq->head);
                        wqe->wr_id = wr->wr_id;
                        wqe->num_sge = wr->num_sge;
-                       for (i = 0; i < wr->num_sge; i++)
-                               wqe->sg_list[i] = wr->sg_list[i];
+                       for (i = 0; i < wr->num_sge; i++) {
+                               wqe->sg_list[i].addr = wr->sg_list[i].addr;
+                               wqe->sg_list[i].length = wr->sg_list[i].length;
+                               wqe->sg_list[i].lkey = wr->sg_list[i].lkey;
+                       }
                        /*
                         * Make sure queue entry is written
                         * before the head index.
@@ -2250,8 +2253,11 @@ int rvt_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
                wqe = rvt_get_rwqe_ptr(&srq->rq, wq->head);
                wqe->wr_id = wr->wr_id;
                wqe->num_sge = wr->num_sge;
-               for (i = 0; i < wr->num_sge; i++)
-                       wqe->sg_list[i] = wr->sg_list[i];
+               for (i = 0; i < wr->num_sge; i++) {
+                       wqe->sg_list[i].addr = wr->sg_list[i].addr;
+                       wqe->sg_list[i].length = wr->sg_list[i].length;
+                       wqe->sg_list[i].lkey = wr->sg_list[i].lkey;
+               }
                /* Make sure queue entry is written before the head index. */
                smp_store_release(&wq->head, next);
                spin_unlock_irqrestore(&srq->rq.kwq->p_lock, flags);
@@ -2259,6 +2265,22 @@ int rvt_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr,
        return 0;
 }
 
+/*
+ * rvt used the internal kernel struct as part of its ABI, for now make sure
+ * the kernel struct does not change layout. FIXME: rvt should never cast the
+ * user struct to a kernel struct.
+ */
+static struct ib_sge *rvt_cast_sge(struct rvt_wqe_sge *sge)
+{
+       BUILD_BUG_ON(offsetof(struct ib_sge, addr) !=
+                    offsetof(struct rvt_wqe_sge, addr));
+       BUILD_BUG_ON(offsetof(struct ib_sge, length) !=
+                    offsetof(struct rvt_wqe_sge, length));
+       BUILD_BUG_ON(offsetof(struct ib_sge, lkey) !=
+                    offsetof(struct rvt_wqe_sge, lkey));
+       return (struct ib_sge *)sge;
+}
+
 /*
  * Validate a RWQE and fill in the SGE state.
  * Return 1 if OK.
@@ -2282,7 +2304,7 @@ static int init_sge(struct rvt_qp *qp, struct rvt_rwqe *wqe)
                        continue;
                /* Check LKEY */
                ret = rvt_lkey_ok(rkt, pd, j ? &ss->sg_list[j - 1] : &ss->sge,
-                                 NULL, &wqe->sg_list[i],
+                                 NULL, rvt_cast_sge(&wqe->sg_list[i]),
                                  IB_ACCESS_LOCAL_WRITE);
                if (unlikely(ret <= 0))
                        goto bad_lkey;
index d2e35d24f1a9e68d271f3f9cf7c16f9a2abe08de..7328293c715cfb0559d841c228083ae4f5bb99ac 100644 (file)
 
 #include <linux/types.h>
 #include <rdma/ib_user_verbs.h>
-#include <rdma/ib_verbs.h>
 #ifndef RDMA_ATOMIC_UAPI
 #define RDMA_ATOMIC_UAPI(_type, _name) struct{ _type val; } _name
 #endif
 
+struct rvt_wqe_sge {
+       __aligned_u64 addr;
+       __u32 length;
+       __u32 lkey;
+};
+
 /*
  * This structure is used to contain the head pointer, tail pointer,
  * and completion queue entries as a single memory allocation so
@@ -39,7 +44,7 @@ struct rvt_rwqe {
        __u64 wr_id;
        __u8 num_sge;
        __u8 padding[7];
-       struct ib_sge sg_list[];
+       struct rvt_wqe_sge sg_list[];
 };
 
 /*