From: sashiko-bot@kernel.org
To: "Abhijit Gangurde" <abhijit.gangurde@amd.com>
Cc: linux-rdma@vger.kernel.org
Subject: Re: [for-next v1 4/5] RDMA/ionic: add Shared receive queue (SRQ) support
Date: Wed, 09 Sep 2026 09:10:22 +0000 [thread overview]
Message-ID: <20260909091023.1C9211F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260908090802.152142-5-abhijit.gangurde@amd.com>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
New issues:
- [High] Kernel CQ polling is broken for SRQ-attached QPs, leading to a permanent CQ stall and dmesg log flood.
- [High] DMA API Violation: Stale CPU cache reads of `resp_buf` on non-cache-coherent architectures.
- [Medium] Unprivileged userspace can trigger unrestricted kernel log spam via conflicting CMB flags.
- [Medium] SRQ Controller Memory Buffer (CMB) initialization is dead code because `srq->rq.cmb` is uninitialized and firmware flags are omitted.
- [Medium] API Contract Violation: `ionic_create_srq` fails to update `attr->attr.max_sge`.
Pre-existing issues:
- [High] Double free / Use-After-Free of `mmap_cmb` entries on error handling paths.
--
commit d21e90481932bd4c2be24a16e0cc7eedd7d8fe39
Author: Amit Kumar <a.k@amd.com>
RDMA/ionic: add Shared receive queue (SRQ) support
This commit implements device-supported verb APIs for shared receive
queues (SRQ) in the ionic RDMA driver.
> diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
> index 884f5665e7a08..6979e0c5a25c2 100644
> --- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
> +++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
[ ... ]
> @@ -2069,6 +2074,42 @@ static void ionic_qp_sq_destroy(struct ionic_ibdev *dev,
> ionic_queue_destroy(&qp->sq, dev->lif_cfg.hwdev);
> }
>
> +static void ionic_rq_mmap_cmb(struct ionic_ibdev *dev,
> + struct ionic_ctx *ctx,
> + struct ionic_rq *rq,
> + u64 *cmb_offset)
> +{
> + bool wc;
> +
> + /* set mapping by default to uncached for
> + * expdb (to guarantee writes order) otherwise
> + * writecombine, unless this default is
> + * overridden by userspace
> + */
> + if ((rq->cmb & (IONIC_CMB_WC | IONIC_CMB_UC)) ==
> + (IONIC_CMB_WC | IONIC_CMB_UC)) {
> + ibdev_warn(&dev->ibdev,
> + "Both rq_cmb flags IONIC_CMB_WC and IONIC_CMB_UC set, using default driver mapping\n");
[Severity: Medium]
Can an unprivileged user trigger unrestricted kernel log spam here?
Since ionic_rq_mmap_cmb() is reachable from userspace QP or SRQ creation
without rate limiting, passing both IONIC_CMB_WC and IONIC_CMB_UC in the
init attributes can flood the dmesg log.
> + rq->cmb &= ~(IONIC_CMB_WC | IONIC_CMB_UC);
> + }
[ ... ]
> +static int ionic_create_srq_cmd(struct ionic_ibdev *dev,
> + struct ionic_ctx *ctx,
> + struct ionic_srq *srq,
> + struct ionic_pd *pd,
> + struct ionic_tbl_buf *buf,
> + u8 udma_mask)
> +{
> + struct ionic_admin_create_srq_resp *resp_buf;
> + const u16 dbid = ionic_ctx_dbid(dev, ctx);
> + struct ionic_admin_wr wr = {
> + .work = COMPLETION_INITIALIZER_ONSTACK(wr.work),
> + .wqe = {
> + .op = IONIC_V1_ADMIN_CREATE_SRQ,
> + .len = cpu_to_le16(IONIC_ADMIN_CREATE_SRQ_IN_V1_LEN),
> + .cmd.create_srq = {
> + .pd_id = cpu_to_le32(pd->pdid),
> + .depth_log2 = srq->rq.q.depth_log2,
> + .stride_log2 = srq->rq.q.stride_log2,
> + .page_size_log2 = buf->page_size_log2,
> + .map_count = cpu_to_le32(buf->tbl_pages),
> + .dma_addr = ionic_pgtbl_dma(buf, 0),
> + .dbid = cpu_to_le16(dbid),
> + .qid = cpu_to_le32(srq->rq.qid),
> + .low_wqes_limit = cpu_to_le16(srq->srq_limit),
> + .udma_mask = udma_mask,
> + }
[Severity: Medium]
Is the IONIC_SRQF_CMB flag missing from this firmware command?
The flags field is left uninitialized (0), so IONIC_SRQF_CMB is never sent
to the firmware even if the user requested a Controller Memory Buffer.
> + }
> + };
[ ... ]
> + ionic_admin_post(dev, &wr);
> +
> + rc = ionic_admin_wait(dev, &wr, 0);
> + if (rc)
> + goto err_admin;
> +
> + if (be32_to_cpu(wr.cqe.status_length) < IONIC_ADMIN_CREATE_SRQ_OUT_V1_LEN) {
> + rc = -EOPNOTSUPP;
> + goto err_admin;
> + }
> +
> + srq->rq.qid = le32_to_cpu(resp_buf->id);
> + srq->udma_idx = resp_buf->udma_idx;
> +
> +err_admin:
> + dma_unmap_single(dev->lif_cfg.hwdev, resp_buf_dma, sizeof(*resp_buf),
> + DMA_FROM_DEVICE);
[Severity: High]
Will this result in stale cache reads on non-cache-coherent architectures?
The CPU accesses resp_buf->id and resp_buf->udma_idx before calling
dma_unmap_single(). On platforms without hardware cache coherency, this
can read stale zeroes from the CPU cache instead of the DMA-written values,
breaking SRQ usage.
> +err_dma:
> + kfree(resp_buf);
> +
> + return rc;
> +}
[ ... ]
> +int ionic_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *attr,
> + struct ib_udata *udata)
> +{
[ ... ]
> + udma_mask = BIT(dev->lif_cfg.udma_count) - 1;
> + if (udata) {
> + rc = ib_copy_validate_udata_in(udata, req, rsvd);
> + if (rc)
> + return rc;
> +
> + udma_mask &= req.udma_mask;
> + }
> +
> + if (!udma_mask)
> + return -EINVAL;
> +
> + rc = ionic_rq_init(dev, ctx, &srq->rq, &req.rq, &buf,
> + attr->attr.max_wr, attr->attr.max_sge,
> + req.rq_spec, udata);
[Severity: Medium]
Does this ignore the user's req.rq_cmb request?
Unlike QP creation which assigns qp->rq.cmb = req.rq_cmb, SRQ creation fails
to copy the field. Because srq is kzalloc'd, srq->rq.cmb remains 0, bypassing
CMB allocation entirely.
> + if (rc)
> + return rc;
> +
> + srq->srq_limit = attr->attr.srq_limit;
[ ... ]
> + ionic_pgtbl_unbuf(dev, &buf);
> + attr->attr.max_wr = srq->rq.q.mask;
> +
> + return 0;
[Severity: Medium]
Is an assignment to attr->attr.max_sge missing here?
Userspace applications rely on the returned capability boundaries. Without
informing the ULP or application of the actual allocated scatter-gather
element limit, they might post too many SGEs.
> +err_resp:
> + if (udata && (srq->rq.cmb & IONIC_CMB_ENABLE))
> + rdma_user_mmap_entry_remove(srq->rq.mmap_cmb);
> +err_mmap_rq:
> + ionic_destroy_srq_cmd(dev, srq->rq.qid);
> +err_cmd:
> + ionic_pgtbl_unbuf(dev, &buf);
> + ionic_rq_destroy(dev, ctx, &srq->rq);
[Severity: High]
This is a pre-existing issue, but does this error path result in a
double-free or use-after-free of the mmap entry?
If ib_respond_udata() fails, rdma_user_mmap_entry_remove(srq->rq.mmap_cmb)
is explicitly called, but the pointer is not zeroed. The cleanup then falls
through to ionic_rq_destroy(), which calls ionic_rq_destroy_cmb() and frees
the exact same pointer again.
> +
> + return rc;
> +}
[ ... ]
> diff --git a/drivers/infiniband/hw/ionic/ionic_datapath.c b/drivers/infiniband/hw/ionic/ionic_datapath.c
> index 9c40b54123d5f..e2d4d441052e6 100644
> --- a/drivers/infiniband/hw/ionic/ionic_datapath.c
> +++ b/drivers/infiniband/hw/ionic/ionic_datapath.c
> @@ -1311,7 +1311,7 @@ static int ionic_post_recv_common(struct ionic_ibdev *dev,
> if (!bad)
> return -EINVAL;
>
> - if (!qp->has_rq) {
> + if (qp->srq) {
> *bad = wr;
> return -EINVAL;
> }
[Severity: High]
Does kernel CQ polling break for SRQ-attached QPs, leading to a permanent
CQ stall and dmesg log flood?
When a userspace application polls the CQ, the kernel's ionic_poll_vcq_cq()
sees IONIC_V1_CQE_TYPE_RECV and calls ionic_poll_recv(). Because SRQ QPs
do not use qp->rq, qp->rq.q is zero-initialized and ionic_queue_empty()
returns true:
ionic_poll_recv() {
if (ionic_queue_empty(&qp->rq.q)) {
ibdev_warn(&dev->ibdev, "qp %u is empty\n", qp->qpid);
return -EIO;
}
...
}
When -EIO is returned, ionic_poll_vcq_cq() skips consuming the CQE:
ionic_poll_vcq_cq() {
...
case IONIC_V1_CQE_TYPE_RECV:
spin_lock(&qp->rq.lock);
rc = ionic_poll_recv(dev, cq, qp, cqe, wc + npolled);
spin_unlock(&qp->rq.lock);
if (rc < 0)
goto out;
...
}
This can permanently wedge the hardware CQ and allow an unprivileged
user to spam the kernel log.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260908090802.152142-1-abhijit.gangurde@amd.com?part=4
next prev parent reply other threads:[~2026-09-09 9:10 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-08 9:07 [for-next v1 0/5] RDMA/ionic: add SRQ support and firmware assigned CQ and SRQ IDs Abhijit Gangurde
2026-09-08 9:07 ` [for-next v1 1/5] net: ionic: Fetch qid allocation and SRQ capability from firmware Abhijit Gangurde
2026-09-09 9:10 ` sashiko-bot
2026-09-08 9:07 ` [for-next v1 2/5] RDMA/ionic: support firmware-assigned CQ IDs Abhijit Gangurde
2026-09-09 9:10 ` sashiko-bot
2026-09-08 9:07 ` [for-next v1 3/5] RDMA/ionic: segregate rq related fields from ionic_qp into a new ionic_rq struct Abhijit Gangurde
2026-09-09 9:10 ` sashiko-bot
2026-09-08 9:08 ` [for-next v1 4/5] RDMA/ionic: add Shared receive queue (SRQ) support Abhijit Gangurde
2026-09-09 9:10 ` sashiko-bot [this message]
2026-09-08 9:08 ` [for-next v1 5/5] RDMA/ionic: implement SRQ event handling support Abhijit Gangurde
2026-09-09 9:10 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260909091023.1C9211F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=abhijit.gangurde@amd.com \
--cc=linux-rdma@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.