Skip to content

Commit 0f2587e

Browse files
committed
Merge: siw: driver update to v6.5
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/3040 JIRA: https://issues.redhat.com/browse/RHEL-2758 Depends: !3015 This MR updates the siw driver to v6.5. Signed-off-by: Kamal Heib <[email protected]> Approved-by: José Ignacio Tornos Martínez <[email protected]> Approved-by: Michal Schmidt <[email protected]> Signed-off-by: Scott Weaver <[email protected]>
2 parents eacab0d + 4470397 commit 0f2587e

File tree

6 files changed

+79
-27
lines changed

6 files changed

+79
-27
lines changed

drivers/infiniband/sw/siw/Kconfig

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
config RDMA_SIW
22
tristate "Software RDMA over TCP/IP (iWARP) driver"
3-
depends on INET && INFINIBAND && LIBCRC32C
3+
depends on INET && INFINIBAND
44
depends on INFINIBAND_VIRT_DMA
5+
select LIBCRC32C
6+
select CRYPTO
7+
select CRYPTO_CRC32C
58
help
69
This driver implements the iWARP RDMA transport over
710
the Linux TCP/IP network stack. It enables a system with a

drivers/infiniband/sw/siw/siw_cq.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc)
5656
if (READ_ONCE(cqe->flags) & SIW_WQE_VALID) {
5757
memset(wc, 0, sizeof(*wc));
5858
wc->wr_id = cqe->id;
59-
wc->status = map_cqe_status[cqe->status].ib;
60-
wc->opcode = map_wc_opcode[cqe->opcode];
6159
wc->byte_len = cqe->bytes;
6260

6361
/*
@@ -71,10 +69,32 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc)
7169
wc->wc_flags = IB_WC_WITH_INVALIDATE;
7270
}
7371
wc->qp = cqe->base_qp;
72+
wc->opcode = map_wc_opcode[cqe->opcode];
73+
wc->status = map_cqe_status[cqe->status].ib;
7474
siw_dbg_cq(cq,
7575
"idx %u, type %d, flags %2x, id 0x%pK\n",
7676
cq->cq_get % cq->num_cqe, cqe->opcode,
7777
cqe->flags, (void *)(uintptr_t)cqe->id);
78+
} else {
79+
/*
80+
* A malicious user may set invalid opcode or
81+
* status in the user mmapped CQE array.
82+
* Sanity check and correct values in that case
83+
* to avoid out-of-bounds access to global arrays
84+
* for opcode and status mapping.
85+
*/
86+
u8 opcode = cqe->opcode;
87+
u16 status = cqe->status;
88+
89+
if (opcode >= SIW_NUM_OPCODES) {
90+
opcode = 0;
91+
status = SIW_WC_GENERAL_ERR;
92+
} else if (status >= SIW_NUM_WC_STATUS) {
93+
status = SIW_WC_GENERAL_ERR;
94+
}
95+
wc->opcode = map_wc_opcode[opcode];
96+
wc->status = map_cqe_status[status].ib;
97+
7898
}
7999
WRITE_ONCE(cqe->flags, 0);
80100
cq->cq_get++;

drivers/infiniband/sw/siw/siw_main.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,6 @@ static int siw_netdev_event(struct notifier_block *nb, unsigned long event,
437437

438438
dev_dbg(&netdev->dev, "siw: event %lu\n", event);
439439

440-
if (dev_net(netdev) != &init_net)
441-
return NOTIFY_OK;
442-
443440
base_dev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_SIW);
444441
if (!base_dev)
445442
return NOTIFY_OK;

drivers/infiniband/sw/siw/siw_mem.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ struct siw_umem *siw_umem_get(u64 start, u64 len, bool writable)
368368
struct mm_struct *mm_s;
369369
u64 first_page_va;
370370
unsigned long mlock_limit;
371-
unsigned int foll_flags = FOLL_WRITE;
371+
unsigned int foll_flags = FOLL_LONGTERM;
372372
int num_pages, num_chunks, i, rv = 0;
373373

374374
if (!can_do_mlock())
@@ -391,14 +391,14 @@ struct siw_umem *siw_umem_get(u64 start, u64 len, bool writable)
391391

392392
mmgrab(mm_s);
393393

394-
if (!writable)
395-
foll_flags |= FOLL_FORCE;
394+
if (writable)
395+
foll_flags |= FOLL_WRITE;
396396

397397
mmap_read_lock(mm_s);
398398

399399
mlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
400400

401-
if (num_pages + atomic64_read(&mm_s->pinned_vm) > mlock_limit) {
401+
if (atomic64_add_return(num_pages, &mm_s->pinned_vm) > mlock_limit) {
402402
rv = -ENOMEM;
403403
goto out_sem_up;
404404
}
@@ -411,38 +411,38 @@ struct siw_umem *siw_umem_get(u64 start, u64 len, bool writable)
411411
goto out_sem_up;
412412
}
413413
for (i = 0; num_pages; i++) {
414-
int got, nents = min_t(int, num_pages, PAGES_PER_CHUNK);
415-
416-
umem->page_chunk[i].plist =
414+
int nents = min_t(int, num_pages, PAGES_PER_CHUNK);
415+
struct page **plist =
417416
kcalloc(nents, sizeof(struct page *), GFP_KERNEL);
418-
if (!umem->page_chunk[i].plist) {
417+
418+
if (!plist) {
419419
rv = -ENOMEM;
420420
goto out_sem_up;
421421
}
422-
got = 0;
422+
umem->page_chunk[i].plist = plist;
423423
while (nents) {
424-
struct page **plist = &umem->page_chunk[i].plist[got];
425-
426-
rv = pin_user_pages(first_page_va, nents,
427-
foll_flags | FOLL_LONGTERM,
424+
rv = pin_user_pages(first_page_va, nents, foll_flags,
428425
plist, NULL);
429426
if (rv < 0)
430427
goto out_sem_up;
431428

432429
umem->num_pages += rv;
433-
atomic64_add(rv, &mm_s->pinned_vm);
434430
first_page_va += rv * PAGE_SIZE;
431+
plist += rv;
435432
nents -= rv;
436-
got += rv;
433+
num_pages -= rv;
437434
}
438-
num_pages -= got;
439435
}
440436
out_sem_up:
441437
mmap_read_unlock(mm_s);
442438

443439
if (rv > 0)
444440
return umem;
445441

442+
/* Adjust accounting for pages not pinned */
443+
if (num_pages)
444+
atomic64_sub(num_pages, &mm_s->pinned_vm);
445+
446446
siw_umem_release(umem, false);
447447

448448
return ERR_PTR(rv);

drivers/infiniband/sw/siw/siw_qp_tx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
551551
data_len -= plen;
552552
fp_off = 0;
553553

554-
if (++seg > (int)MAX_ARRAY) {
554+
if (++seg >= (int)MAX_ARRAY) {
555555
siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
556556
siw_unmap_pages(iov, kmap_mask, seg-1);
557557
wqe->processed -= c_tx->bytes_unsent;

drivers/infiniband/sw/siw/siw_verbs.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -676,13 +676,45 @@ static int siw_copy_inline_sgl(const struct ib_send_wr *core_wr,
676676
static int siw_sq_flush_wr(struct siw_qp *qp, const struct ib_send_wr *wr,
677677
const struct ib_send_wr **bad_wr)
678678
{
679-
struct siw_sqe sqe = {};
680679
int rv = 0;
681680

682681
while (wr) {
683-
sqe.id = wr->wr_id;
684-
sqe.opcode = wr->opcode;
685-
rv = siw_sqe_complete(qp, &sqe, 0, SIW_WC_WR_FLUSH_ERR);
682+
struct siw_sqe sqe = {};
683+
684+
switch (wr->opcode) {
685+
case IB_WR_RDMA_WRITE:
686+
sqe.opcode = SIW_OP_WRITE;
687+
break;
688+
case IB_WR_RDMA_READ:
689+
sqe.opcode = SIW_OP_READ;
690+
break;
691+
case IB_WR_RDMA_READ_WITH_INV:
692+
sqe.opcode = SIW_OP_READ_LOCAL_INV;
693+
break;
694+
case IB_WR_SEND:
695+
sqe.opcode = SIW_OP_SEND;
696+
break;
697+
case IB_WR_SEND_WITH_IMM:
698+
sqe.opcode = SIW_OP_SEND_WITH_IMM;
699+
break;
700+
case IB_WR_SEND_WITH_INV:
701+
sqe.opcode = SIW_OP_SEND_REMOTE_INV;
702+
break;
703+
case IB_WR_LOCAL_INV:
704+
sqe.opcode = SIW_OP_INVAL_STAG;
705+
break;
706+
case IB_WR_REG_MR:
707+
sqe.opcode = SIW_OP_REG_MR;
708+
break;
709+
default:
710+
rv = -EINVAL;
711+
break;
712+
}
713+
if (!rv) {
714+
sqe.id = wr->wr_id;
715+
rv = siw_sqe_complete(qp, &sqe, 0,
716+
SIW_WC_WR_FLUSH_ERR);
717+
}
686718
if (rv) {
687719
if (bad_wr)
688720
*bad_wr = wr;

0 commit comments

Comments
 (0)