From: Leon Romanovsky <[email protected]>

The destroy callbacks currently zero the udata output after tearing down
their resources. If that userspace access fails, uverbs preserves the
uobject and permits the destroy callback to be entered again even though
the driver resource has already been released.

Use ib_no_udata_io() before teardown so all udata failures occur while the
resource is still intact, then return success after teardown completes.

Fixes: bed686d8dcd4 ("RDMA/bnxt_re: Use ib_respond_empty_udata()")
Signed-off-by: Leon Romanovsky <[email protected]>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c 
b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 565762529007..ef9943be1886 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -695,7 +695,7 @@ int bnxt_re_dealloc_pd(struct ib_pd *ib_pd, struct ib_udata 
*udata)
        struct bnxt_re_dev *rdev = pd->rdev;
        int ret;
 
-       ret = ib_is_udata_in_empty(udata);
+       ret = ib_no_udata_io(udata);
        if (ret)
                return ret;
 
@@ -712,7 +712,7 @@ int bnxt_re_dealloc_pd(struct ib_pd *ib_pd, struct ib_udata 
*udata)
                                           &pd->qplib_pd))
                        atomic_dec(&rdev->stats.res.pd_count);
        }
-       return ib_respond_empty_udata(udata);
+       return 0;
 }
 
 int bnxt_re_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
@@ -1015,7 +1015,7 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct 
ib_udata *udata)
        unsigned int flags;
        int rc;
 
-       rc = ib_is_udata_in_empty(udata);
+       rc = ib_no_udata_io(udata);
        if (rc)
                return rc;
 
@@ -1064,7 +1064,7 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct 
ib_udata *udata)
        if (scq_nq != rcq_nq)
                bnxt_re_synchronize_nq(rcq_nq);
 
-       return ib_respond_empty_udata(udata);
+       return 0;
 }
 
 static u8 __from_ib_qp_type(enum ib_qp_type type)
@@ -2148,7 +2148,7 @@ int bnxt_re_destroy_srq(struct ib_srq *ib_srq, struct 
ib_udata *udata)
        struct bnxt_qplib_srq *qplib_srq = &srq->qplib_srq;
        int ret;
 
-       ret = ib_is_udata_in_empty(udata);
+       ret = ib_no_udata_io(udata);
        if (ret)
                return ret;
 
@@ -2159,7 +2159,7 @@ int bnxt_re_destroy_srq(struct ib_srq *ib_srq, struct 
ib_udata *udata)
                free_page((unsigned long)srq->uctx_srq_page);
        ib_umem_release(srq->umem);
        atomic_dec(&rdev->stats.res.srq_count);
-       return ib_respond_empty_udata(udata);
+       return 0;
 }
 
 static int bnxt_re_init_user_srq(struct bnxt_re_dev *rdev,
@@ -3471,7 +3471,7 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct 
ib_udata *udata)
        nq = cq->qplib_cq.nq;
        cctx = rdev->chip_ctx;
 
-       ret = ib_is_udata_in_empty(udata);
+       ret = ib_no_udata_io(udata);
        if (ret)
                return ret;
 
@@ -3486,7 +3486,7 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct 
ib_udata *udata)
        atomic_dec(&rdev->stats.res.cq_count);
        kfree(cq->cql);
        ib_umem_release(cq->umem);
-       return ib_respond_empty_udata(udata);
+       return 0;
 }
 
 int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr 
*attr,
@@ -4449,7 +4449,7 @@ int bnxt_re_dereg_mr(struct ib_mr *ib_mr, struct ib_udata 
*udata)
        struct bnxt_re_dev *rdev = mr->rdev;
        int rc;
 
-       rc = ib_is_udata_in_empty(udata);
+       rc = ib_no_udata_io(udata);
        if (rc)
                return rc;
 
@@ -4472,7 +4472,7 @@ int bnxt_re_dereg_mr(struct ib_mr *ib_mr, struct ib_udata 
*udata)
        atomic_dec(&rdev->stats.res.mr_count);
        if (rc)
                return rc;
-       return ib_respond_empty_udata(udata);
+       return 0;
 }
 
 static int bnxt_re_set_page(struct ib_mr *ib_mr, u64 addr)

-- 
2.54.0


Reply via email to