All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "David Hu" <dhu@x6u.co>
Cc: linux-rdma@vger.kernel.org
Subject: Re: [PATCH rdma-next v3 3/6] RDMA/irdma: Support UMEM attribute for QP creation
Date: Fri, 16 Oct 2026 20:46:15 +0000	[thread overview]
Message-ID: <sashiko-outbox-174922@kernel.org> (raw)
In-Reply-To: <20261016202909.1289496-4-dhu@x6u.co>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] RDMA/irdma: invalid sg_page() on dmabuf QP umem in irdma_copy_user_pgaddrs()
--

commit 200a925805870f2d575192eafe96be3cef694b7d
Author: David Hu <xuehaohu@google.com>

RDMA/irdma: Support UMEM attribute for QP creation

This commit adds support for the 1-step queue buffer creation model for QPs
via UVERBS_ATTR_CREATE_QP_BUF_UMEM and ib_umem_get_attr(), while retaining
backward compatibility with the legacy 2-step MR registration model.

> diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
> index b2ffdc8e3d677..ab25445f38282 100644
> --- a/drivers/infiniband/hw/irdma/verbs.c
> +++ b/drivers/infiniband/hw/irdma/verbs.c
[ ... ]
> @@ -713,6 +708,52 @@ static int irdma_setup_umode_qp(struct irdma_ucontext *ucontext,
>  		ukinfo->rq_size = ukinfo->rq_depth >> ukinfo->rq_shift;
>  	}
>  
> +	if (attrs && uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_QP_BUF_UMEM)) {
> +		struct irdma_mem_reg_req qp_req = {};
> +		struct ib_umem *umem;
> +		u32 total;
> +
> +		/* Legacy context does not provide depth info */
> +		if (!ucontext->use_raw_attrs)
> +			return -EOPNOTSUPP;
> +
> +		qp_req.sq_pages = DIV_ROUND_UP(ukinfo->sq_depth * IRDMA_QP_WQE_MIN_SIZE,
> +					       IRDMA_HW_PAGE_SIZE);
> +		/* In case srq is used, this will be a single page */
> +		qp_req.rq_pages = DIV_ROUND_UP(ukinfo->rq_depth * IRDMA_QP_WQE_MIN_SIZE,
> +					       IRDMA_HW_PAGE_SIZE);
> +		total = qp_req.sq_pages + qp_req.rq_pages + IRDMA_SHADOW_PGCNT;
> +
> +		umem = ib_umem_get_attr(&iwdev->ibdev, attrs,
> +					UVERBS_ATTR_CREATE_QP_BUF_UMEM,
> +					total << IRDMA_HW_PAGE_SHIFT,
> +					IB_ACCESS_LOCAL_WRITE);
> +		if (IS_ERR(umem))
> +			return PTR_ERR(umem);
> +
> +		iwqp->iwpbl = irdma_setup_q_pbl_from_umem(iwdev, umem,
> +							  iwqp->ibqp.pd,
> +							  IRDMA_MEMREG_TYPE_QP,
> +							  &qp_req);
[ ... ]
> @@ -3532,6 +3574,64 @@ static void irdma_free_iwmr(struct irdma_mr *iwmr)
>  	kfree(iwmr);
>  }
>  
> +static struct irdma_pbl *irdma_setup_q_pbl_from_umem(struct irdma_device *iwdev,
> +						     struct ib_umem *region,
> +						     struct ib_pd *pd,
> +						     enum irdma_memreg_type reg_type,
> +						     struct irdma_mem_reg_req *req)
> +{
> +	struct irdma_pbl *iwpbl;
> +	struct irdma_mr *iwmr;
> +	u32 total;
> +	u8 lvl;
> +	int err;
> +
> +	/* iWarp: Catch page not starting on OS page boundary */
> +	if (!rdma_protocol_roce(&iwdev->ibdev, 1) && ib_umem_offset(region))
> +		return ERR_PTR(-EINVAL);

[Severity: Critical]
Can passing an IB_UVERBS_BUFFER_TYPE_DMABUF descriptor via
UVERBS_ATTR_CREATE_QP_BUF_UMEM cause a NULL pointer dereference or write to
the wrong page during iWARP connection establishment?

In irdma_setup_umode_qp(), ib_umem_get_attr() resolves the buffer descriptor
through __ib_umem_get_desc_dir(), which accepts both IB_UVERBS_BUFFER_TYPE_VA
and IB_UVERBS_BUFFER_TYPE_DMABUF. Previously, IRDMA_MEMREG_TYPE_QP MRs could
only be registered via irdma_reg_user_mr() -> ib_umem_get_va(), whereas
irdma_reg_user_mr_dmabuf() hardcoded IRDMA_MEMREG_TYPE_MEM.

When irdma_setup_q_pbl_from_umem() calls irdma_handle_q_mem() ->
irdma_setup_pbles() -> irdma_copy_user_pgaddrs(), the driver extracts the
first SQ page from the scatterlist:

drivers/infiniband/hw/irdma/verbs.c:irdma_copy_user_pgaddrs() {
	if (iwmr->type == IRDMA_MEMREG_TYPE_QP)
		iwpbl->qp_mr.sq_page = sg_page(region->sgt_append.sgt.sgl);
}

and irdma_setup_virt_qp() assigns iwqp->page = qpmr->sq_page, while
iwqp->sc_qp.qp_uk.sq_base remains NULL for a user-mode QP.

On an iWARP device, irdma_accept() and irdma_cm_event_connected() map
iwqp->page to write the LSMM or RTT WQE:

drivers/infiniband/hw/irdma/cm.c:irdma_accept() {
	if (iwqp->page)
		iwqp->sc_qp.qp_uk.sq_base = kmap_local_page(iwqp->page);

	cm_node->lsmm_size = accept.size + conn_param->private_data_len;
	irdma_sc_send_lsmm(&iwqp->sc_qp, iwqp->ietf_mem.va, cm_node->lsmm_size,
			   ibmr->lkey);
}

drivers/infiniband/hw/irdma/cm.c:irdma_cm_event_connected() {
	if (iwqp->page)
		iwqp->sc_qp.qp_uk.sq_base = kmap_local_page(iwqp->page);
	irdma_sc_send_rtt(&iwqp->sc_qp, read0);
	if (iwqp->page)
		kunmap_local(iwqp->sc_qp.qp_uk.sq_base);
}

With a dmabuf-backed ib_umem, calling sg_page() on the scatterlist breaks in
two ways:

1. When CONFIG_DMABUF_DEBUG is enabled (where dma_buf_wrap_sg_table() clears
   page_link) or when the exporter does not populate struct page pointers
   (such as uverbs_dmabuf or P2P/MMIO exporters), sg_page() returns NULL.
   This leaves iwqp->page NULL, so irdma_accept() and
   irdma_cm_event_connected() skip kmap_local_page() and pass a NULL
   qp_uk->sq_base into irdma_sc_send_lsmm() / irdma_sc_send_rtt(), which
   immediately dereferences qp_uk->sq_base->elem.

2. Even when sg_page() is populated by a system-RAM exporter, if userspace
   passes a non-zero page-aligned offset within a coalesced multi-page SG
   entry, ib_umem_dmabuf_map_pages() advances sg_dma_address(sg) and
   decrements sg_dma_len(sg) in place without updating sg->page_link:

   drivers/infiniband/core/umem_dmabuf.c:ib_umem_dmabuf_map_pages() {
		if (cur <= start && start < cur + sg_dma_len(sg)) {
			unsigned long offset = start - cur;

			umem_dmabuf->first_sg = sg;
			umem_dmabuf->first_sg_offset = offset;
			sg_dma_address(sg) += offset;
			sg_dma_len(sg) -= offset;
			cur += offset;
		}
   }

   As a result, sg_page(region->sgt_append.sgt.sgl) points to the start of
   that SG segment rather than the SQ page at the requested offset, causing
   kmap_local_page(iwqp->page) to map and overwrite the wrong page.

Should irdma_setup_q_pbl_from_umem() (or irdma_setup_umode_qp()) reject
region->is_dmabuf, at least when !rdma_protocol_roce(&iwdev->ibdev, 1) (or
unconditionally if dmabuf queue rings are not supported)?

> +
> +	iwmr = irdma_alloc_iwmr(region, &iwdev->ibdev, pd, region->address, reg_type);
> +	if (IS_ERR(iwmr))
> +		return ERR_CAST(iwmr);
[ ... ]

ওয়াও! (Wait, let me make sure there is no extra text at the end! Oh! Why did those characters appear? Let me remove that!)

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261016202909.1289496-1-dhu@x6u.co?part=3

  reply	other threads:[~2026-10-16 20:46 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 20:29 [PATCH rdma-next v3 0/6] RDMA/irdma: Add support for ioctl David Hu
2026-10-16 20:29 ` [PATCH rdma-next v3 1/6] RDMA/irdma: Plumb uverbs_attr_bundle for QP, SRQ David Hu
2026-10-16 20:31   ` sashiko-bot
2026-10-16 20:29 ` [PATCH rdma-next v3 2/6] RDMA/irdma: Register irdma UVERBS ioctl namespace David Hu
2026-10-16 20:37   ` sashiko-bot
2026-10-16 20:29 ` [PATCH rdma-next v3 3/6] RDMA/irdma: Support UMEM attribute for QP creation David Hu
2026-10-16 20:46   ` sashiko-bot [this message]
2026-10-16 20:29 ` [PATCH rdma-next v3 4/6] RDMA/irdma: Split CQ setup to umode and kmode David Hu
2026-10-16 20:44   ` sashiko-bot
2026-10-16 20:29 ` [PATCH rdma-next v3 5/6] RDMA/irdma: Support UMEM attribute for CQ creation David Hu
2026-10-16 20:56   ` sashiko-bot
2026-10-16 20:29 ` [PATCH rdma-next v3 6/6] RDMA/irdma: Support UMEM attribute for SRQ creation David Hu
2026-10-16 20:41   ` 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=sashiko-outbox-174922@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dhu@x6u.co \
    --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.