Skip to content

Commit 61a0925

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma fixes from Jason Gunthorpe: "Nothing particularly exciting, some small ODP regressions from the mmu notifier rework, another bunch of syzkaller fixes, and a bug fix for a botched syzkaller fix in the first rc pull request. - Fix busted syzkaller fix in 'get_new_pps' - this turned out to crash on certain HW configurations - Bug fixes for various missed things in error unwinds - Add a missing rcu_read_lock annotation in hfi/qib - Fix two ODP related regressions from the recent mmu notifier changes - Several more syzkaller bugs in siw, RDMA netlink, verbs and iwcm - Revert an old patch in CMA as it is now shown to not be allocating port numbers properly" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/iwcm: Fix iwcm work deallocation RDMA/siw: Fix failure handling during device creation RDMA/nldev: Fix crash when set a QP to a new counter but QPN is missing RDMA/odp: Ensure the mm is still alive before creating an implicit child RDMA/core: Fix protection fault in ib_mr_pool_destroy IB/mlx5: Fix implicit ODP race IB/hfi1, qib: Ensure RCU is locked when accessing list RDMA/core: Fix pkey and port assignment in get_new_pps RMDA/cm: Fix missing ib_cm_destroy_id() in ib_cm_insert_listen() RDMA/rw: Fix error flow during RDMA context initialization RDMA/core: Fix use of logical OR in get_new_pps Revert "RDMA/cma: Simplify rdma_resolve_addr() error flow"
2 parents c200376 + 810dbc6 commit 61a0925

File tree

15 files changed

+95
-59
lines changed

15 files changed

+95
-59
lines changed

drivers/infiniband/core/cm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,6 +1191,7 @@ struct ib_cm_id *ib_cm_insert_listen(struct ib_device *device,
11911191
/* Sharing an ib_cm_id with different handlers is not
11921192
* supported */
11931193
spin_unlock_irqrestore(&cm.lock, flags);
1194+
ib_destroy_cm_id(cm_id);
11941195
return ERR_PTR(-EINVAL);
11951196
}
11961197
refcount_inc(&cm_id_priv->refcount);

drivers/infiniband/core/cma.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3212,19 +3212,26 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
32123212
int ret;
32133213

32143214
id_priv = container_of(id, struct rdma_id_private, id);
3215+
memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
32153216
if (id_priv->state == RDMA_CM_IDLE) {
32163217
ret = cma_bind_addr(id, src_addr, dst_addr);
3217-
if (ret)
3218+
if (ret) {
3219+
memset(cma_dst_addr(id_priv), 0,
3220+
rdma_addr_size(dst_addr));
32183221
return ret;
3222+
}
32193223
}
32203224

3221-
if (cma_family(id_priv) != dst_addr->sa_family)
3225+
if (cma_family(id_priv) != dst_addr->sa_family) {
3226+
memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr));
32223227
return -EINVAL;
3228+
}
32233229

3224-
if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY))
3230+
if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) {
3231+
memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr));
32253232
return -EINVAL;
3233+
}
32263234

3227-
memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
32283235
if (cma_any_addr(dst_addr)) {
32293236
ret = cma_resolve_loopback(id_priv);
32303237
} else {

drivers/infiniband/core/core_priv.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,20 @@ static inline struct ib_qp *_ib_create_qp(struct ib_device *dev,
338338
qp->pd = pd;
339339
qp->uobject = uobj;
340340
qp->real_qp = qp;
341+
342+
qp->qp_type = attr->qp_type;
343+
qp->rwq_ind_tbl = attr->rwq_ind_tbl;
344+
qp->send_cq = attr->send_cq;
345+
qp->recv_cq = attr->recv_cq;
346+
qp->srq = attr->srq;
347+
qp->rwq_ind_tbl = attr->rwq_ind_tbl;
348+
qp->event_handler = attr->event_handler;
349+
350+
atomic_set(&qp->usecnt, 0);
351+
spin_lock_init(&qp->mr_lock);
352+
INIT_LIST_HEAD(&qp->rdma_mrs);
353+
INIT_LIST_HEAD(&qp->sig_mrs);
354+
341355
/*
342356
* We don't track XRC QPs for now, because they don't have PD
343357
* and more importantly they are created internaly by driver,

drivers/infiniband/core/iwcm.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,10 @@ static void dealloc_work_entries(struct iwcm_id_private *cm_id_priv)
159159
{
160160
struct list_head *e, *tmp;
161161

162-
list_for_each_safe(e, tmp, &cm_id_priv->work_free_list)
162+
list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) {
163+
list_del(e);
163164
kfree(list_entry(e, struct iwcm_work, free_list));
165+
}
164166
}
165167

166168
static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count)

drivers/infiniband/core/nldev.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,8 @@ static int nldev_stat_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
17571757
if (ret)
17581758
goto err_msg;
17591759
} else {
1760+
if (!tb[RDMA_NLDEV_ATTR_RES_LQPN])
1761+
goto err_msg;
17601762
qpn = nla_get_u32(tb[RDMA_NLDEV_ATTR_RES_LQPN]);
17611763
if (tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]) {
17621764
cntn = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]);

drivers/infiniband/core/rw.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,23 @@ static int rdma_rw_init_single_wr(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
273273
return 1;
274274
}
275275

276+
static void rdma_rw_unmap_sg(struct ib_device *dev, struct scatterlist *sg,
277+
u32 sg_cnt, enum dma_data_direction dir)
278+
{
279+
if (is_pci_p2pdma_page(sg_page(sg)))
280+
pci_p2pdma_unmap_sg(dev->dma_device, sg, sg_cnt, dir);
281+
else
282+
ib_dma_unmap_sg(dev, sg, sg_cnt, dir);
283+
}
284+
285+
static int rdma_rw_map_sg(struct ib_device *dev, struct scatterlist *sg,
286+
u32 sg_cnt, enum dma_data_direction dir)
287+
{
288+
if (is_pci_p2pdma_page(sg_page(sg)))
289+
return pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir);
290+
return ib_dma_map_sg(dev, sg, sg_cnt, dir);
291+
}
292+
276293
/**
277294
* rdma_rw_ctx_init - initialize a RDMA READ/WRITE context
278295
* @ctx: context to initialize
@@ -295,11 +312,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,
295312
struct ib_device *dev = qp->pd->device;
296313
int ret;
297314

298-
if (is_pci_p2pdma_page(sg_page(sg)))
299-
ret = pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir);
300-
else
301-
ret = ib_dma_map_sg(dev, sg, sg_cnt, dir);
302-
315+
ret = rdma_rw_map_sg(dev, sg, sg_cnt, dir);
303316
if (!ret)
304317
return -ENOMEM;
305318
sg_cnt = ret;
@@ -338,7 +351,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,
338351
return ret;
339352

340353
out_unmap_sg:
341-
ib_dma_unmap_sg(dev, sg, sg_cnt, dir);
354+
rdma_rw_unmap_sg(dev, sg, sg_cnt, dir);
342355
return ret;
343356
}
344357
EXPORT_SYMBOL(rdma_rw_ctx_init);
@@ -588,11 +601,7 @@ void rdma_rw_ctx_destroy(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num,
588601
break;
589602
}
590603

591-
if (is_pci_p2pdma_page(sg_page(sg)))
592-
pci_p2pdma_unmap_sg(qp->pd->device->dma_device, sg,
593-
sg_cnt, dir);
594-
else
595-
ib_dma_unmap_sg(qp->pd->device, sg, sg_cnt, dir);
604+
rdma_rw_unmap_sg(qp->pd->device, sg, sg_cnt, dir);
596605
}
597606
EXPORT_SYMBOL(rdma_rw_ctx_destroy);
598607

drivers/infiniband/core/security.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,15 +340,19 @@ static struct ib_ports_pkeys *get_new_pps(const struct ib_qp *qp,
340340
return NULL;
341341

342342
if (qp_attr_mask & IB_QP_PORT)
343-
new_pps->main.port_num =
344-
(qp_pps) ? qp_pps->main.port_num : qp_attr->port_num;
343+
new_pps->main.port_num = qp_attr->port_num;
344+
else if (qp_pps)
345+
new_pps->main.port_num = qp_pps->main.port_num;
346+
345347
if (qp_attr_mask & IB_QP_PKEY_INDEX)
346-
new_pps->main.pkey_index = (qp_pps) ? qp_pps->main.pkey_index :
347-
qp_attr->pkey_index;
348+
new_pps->main.pkey_index = qp_attr->pkey_index;
349+
else if (qp_pps)
350+
new_pps->main.pkey_index = qp_pps->main.pkey_index;
351+
348352
if ((qp_attr_mask & IB_QP_PKEY_INDEX) && (qp_attr_mask & IB_QP_PORT))
349353
new_pps->main.state = IB_PORT_PKEY_VALID;
350354

351-
if (!(qp_attr_mask & (IB_QP_PKEY_INDEX || IB_QP_PORT)) && qp_pps) {
355+
if (!(qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) && qp_pps) {
352356
new_pps->main.port_num = qp_pps->main.port_num;
353357
new_pps->main.pkey_index = qp_pps->main.pkey_index;
354358
if (qp_pps->main.state != IB_PORT_PKEY_NOT_VALID)

drivers/infiniband/core/umem_odp.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,28 @@ ib_umem_odp_alloc_child(struct ib_umem_odp *root, unsigned long addr,
181181
odp_data->page_shift = PAGE_SHIFT;
182182
odp_data->notifier.ops = ops;
183183

184+
/*
185+
* A mmget must be held when registering a notifier, the owming_mm only
186+
* has a mm_grab at this point.
187+
*/
188+
if (!mmget_not_zero(umem->owning_mm)) {
189+
ret = -EFAULT;
190+
goto out_free;
191+
}
192+
184193
odp_data->tgid = get_pid(root->tgid);
185194
ret = ib_init_umem_odp(odp_data, ops);
186-
if (ret) {
187-
put_pid(odp_data->tgid);
188-
kfree(odp_data);
189-
return ERR_PTR(ret);
190-
}
195+
if (ret)
196+
goto out_tgid;
197+
mmput(umem->owning_mm);
191198
return odp_data;
199+
200+
out_tgid:
201+
put_pid(odp_data->tgid);
202+
mmput(umem->owning_mm);
203+
out_free:
204+
kfree(odp_data);
205+
return ERR_PTR(ret);
192206
}
193207
EXPORT_SYMBOL(ib_umem_odp_alloc_child);
194208

drivers/infiniband/core/uverbs_cmd.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,16 +1445,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
14451445
if (ret)
14461446
goto err_cb;
14471447

1448-
qp->pd = pd;
1449-
qp->send_cq = attr.send_cq;
1450-
qp->recv_cq = attr.recv_cq;
1451-
qp->srq = attr.srq;
1452-
qp->rwq_ind_tbl = ind_tbl;
1453-
qp->event_handler = attr.event_handler;
1454-
qp->qp_type = attr.qp_type;
1455-
atomic_set(&qp->usecnt, 0);
14561448
atomic_inc(&pd->usecnt);
1457-
qp->port = 0;
14581449
if (attr.send_cq)
14591450
atomic_inc(&attr.send_cq->usecnt);
14601451
if (attr.recv_cq)

drivers/infiniband/core/verbs.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,16 +1185,6 @@ struct ib_qp *ib_create_qp_user(struct ib_pd *pd,
11851185
if (ret)
11861186
goto err;
11871187

1188-
qp->qp_type = qp_init_attr->qp_type;
1189-
qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl;
1190-
1191-
atomic_set(&qp->usecnt, 0);
1192-
qp->mrs_used = 0;
1193-
spin_lock_init(&qp->mr_lock);
1194-
INIT_LIST_HEAD(&qp->rdma_mrs);
1195-
INIT_LIST_HEAD(&qp->sig_mrs);
1196-
qp->port = 0;
1197-
11981188
if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {
11991189
struct ib_qp *xrc_qp =
12001190
create_xrc_qp_user(qp, qp_init_attr, udata);

0 commit comments

Comments
 (0)