Merge git://www.linux-watchdog.org/linux-watchdog
[sfrench/cifs-2.6.git] / drivers / infiniband / core / verbs.c
index 4792f5209ac24c62cdcb45ce373a4365dbf997c3..c973a83c898b487710600f4e4f6441c99595ca6c 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <net/addrconf.h>
+#include <linux/security.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_cache.h>
@@ -713,11 +714,19 @@ static struct ib_qp *__ib_open_qp(struct ib_qp *real_qp,
 {
        struct ib_qp *qp;
        unsigned long flags;
+       int err;
 
        qp = kzalloc(sizeof *qp, GFP_KERNEL);
        if (!qp)
                return ERR_PTR(-ENOMEM);
 
+       qp->real_qp = real_qp;
+       err = ib_open_shared_qp_security(qp, real_qp->device);
+       if (err) {
+               kfree(qp);
+               return ERR_PTR(err);
+       }
+
        qp->real_qp = real_qp;
        atomic_inc(&real_qp->usecnt);
        qp->device = real_qp->device;
@@ -804,6 +813,12 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
        if (IS_ERR(qp))
                return qp;
 
+       ret = ib_create_qp_security(qp, device);
+       if (ret) {
+               ib_destroy_qp(qp);
+               return ERR_PTR(ret);
+       }
+
        qp->device     = device;
        qp->real_qp    = qp;
        qp->uobject    = NULL;
@@ -1266,7 +1281,7 @@ int ib_modify_qp(struct ib_qp *qp,
                        return ret;
        }
 
-       return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
+       return ib_security_modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
 }
 EXPORT_SYMBOL(ib_modify_qp);
 
@@ -1295,6 +1310,7 @@ int ib_close_qp(struct ib_qp *qp)
        spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags);
 
        atomic_dec(&real_qp->usecnt);
+       ib_close_shared_qp_security(qp->qp_sec);
        kfree(qp);
 
        return 0;
@@ -1335,6 +1351,7 @@ int ib_destroy_qp(struct ib_qp *qp)
        struct ib_cq *scq, *rcq;
        struct ib_srq *srq;
        struct ib_rwq_ind_table *ind_tbl;
+       struct ib_qp_security *sec;
        int ret;
 
        WARN_ON_ONCE(qp->mrs_used > 0);
@@ -1350,6 +1367,9 @@ int ib_destroy_qp(struct ib_qp *qp)
        rcq  = qp->recv_cq;
        srq  = qp->srq;
        ind_tbl = qp->rwq_ind_tbl;
+       sec  = qp->qp_sec;
+       if (sec)
+               ib_destroy_qp_security_begin(sec);
 
        if (!qp->uobject)
                rdma_rw_cleanup_mrs(qp);
@@ -1366,6 +1386,11 @@ int ib_destroy_qp(struct ib_qp *qp)
                        atomic_dec(&srq->usecnt);
                if (ind_tbl)
                        atomic_dec(&ind_tbl->usecnt);
+               if (sec)
+                       ib_destroy_qp_security_end(sec);
+       } else {
+               if (sec)
+                       ib_destroy_qp_security_abort(sec);
        }
 
        return ret;