From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F75C423E9C for ; Wed, 7 Oct 2026 21:27:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791408465; cv=none; b=T62C6/bTGMojLGqkBAqkHt8/O3hULTFH1j8145qBiDKojU0g5u2XgihVwLTqo+kDkn4Ads5aQUTpMEkQZh9KNq64DOSS+SxFOb79GGFPqXx+vKq8mfEwG6S31kP2st38YVzIhhfUluJsnWYNEQ1N0vkB3nsF8cG5L2/XlwAhLNA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791408465; c=relaxed/simple; bh=LpK3MlRuVJxJxtDhXN32lu/uryl0DBZALWksguoyIXE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SDDMnQ8ptaigUjfY2Qi8DN64viqv1xwulzj1ks5/+HaEBKPLbgW0D7+S6R9bl1UceRQxsgYiW6R0HLCyBZGtsTPPI33F7oabC0pp0TglVyD5MPRPt7/31zvNjbH5ZqKqc+h3VgDzYSlANMyy5PH9dUq/icCgh2ZEkGRWbF/Yvhg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PFuql5PL; arc=none smtp.client-ip=209.85.128.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PFuql5PL" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-4a1698ea378so19863855e9.2 for ; Wed, 07 Oct 2026 14:27:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791408462; x=1792013262; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OtBP7HWDVtqSxKO/0UtHBQZZgW6BHdDPHdI/ZgBGR9s=; b=PFuql5PLgLxtN+P1t7XxG4dZbhte/BwfW7gcXmXTJq81fkfusR/8RmgEYn0g/xWzFM 3dnk0D9euvw1Uoj0uGwvL2CHIzHK4eRypx6A0i8/Ls9W5Mk/sSGmpPNPNQ0ssoGTkzvK IB7VUMTrT3s4vdP/tCC20br7az81OGkDKhVYikrCGg0NKkXOl/LJVgxjlYCaRTxg9uZ5 YDK2GR91nf8f7rRTm2H1SAz+GjgBKyKRsXoSJJLJuM1jMFfxwOv0Cj/agJmtdSbV/vqI 0jL/LzMRVw6SHRx7aHajkYgOuu+5nnppoVev3aE2Spz5gnmJcAIeFNF5rBaEh1UDnk1L SOMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791408462; x=1792013262; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OtBP7HWDVtqSxKO/0UtHBQZZgW6BHdDPHdI/ZgBGR9s=; b=oI8HtENsiZZMLwkrevTL8LjOxStszjna9LGg4z2TPxa3VKjHWkKK4a2P7Cgda2XRbY WZGhUWUSdFev5yIbOxvf7X7HocYI/0x9efd6poV1JltlSxwbu0z723vv2Yu3rqt8m2Eo RLQ2REcbBZNxtjRPAzG+SktosHy3zucZg9J/jJB0ylarmKk3z12gyO+dj85xmA+GPbvn g2VkUVIPhIUJ+3ejn7d4K6vkdclXNCapwqpO3FmMvpei9mVVAnwDjpt28be4L/m02Cj3 oQbdy4IYnugsF7WmF3ks7ZxS2MyL4zOcSVbuOzYm4PdTkKO0AfLO1UtzZFrd6mtcHrei 4RmQ== X-Forwarded-Encrypted: i=1; AKwUvBzXHhspdTouQWR7/x8a+EqU5bDo1GRb6SabQ4yKHQ5viieI15pxwz1ABmyAIgP0ryR3BnZFhQeHB5P33PY=@vger.kernel.org X-Gm-Message-State: AFuF++lIf/4ySNGRxS2JtXCm+pgGwPAa56H/eOP6N9B8RT0oJkt8RbUY Pb33N7ebyh0HR9Ag2wQ8haHgzJIAK/vxKnl7cE7DT7wKiMWC/TUuCn4= X-Gm-Gg: AYBFou3y3//ADqXzO1+duASc6GJ2NONh+Mc0rw0JPJqIpCd4vwLjou8RE84ddk4RtKv R81Fzkvi6N/uPbrtfCc3JE1Cmg6JiEpLwqKmgZBy72KYBmkM1mf5JprLFIu5FTzwH3aAa+wjmvm rzjU/rwg03hlbWpBmKGNmeHCoQd0DV4D9TDLJRtCfN2h7vce24Wcj+QusMI7ripw0NV6eeYguto hjIWL8izKiuNwiDXKD8acLZIznUSqm6WZH5g/c77xCIUNQoHiBn+3jiBmqVF02ZEHsPc/zBUaP6 NraAZ2EFljgk5AmMrdxx6W2N5N0zpv73Cu7S+OC2dOXX0XhHlOTn2Ac39c5zQH3PQzGFOz0T1pi v8/d3K2Yn3K9ZvrFkzcyCP/Pme5aWSt3LD75ybLB9gP3e5gwvmPjTsWDHTiyd06seX2zR6mYW1F 6BGPWam5lrLrjcM+RJJGjUiWl5Nzu3krc0dTGMx9g= X-Received: by 2002:a05:600c:5254:b0:4a0:1b15:8852 with SMTP id 5b1f17b1804b1-4a180310d31mr58481475e9.16.1791408461660; Wed, 07 Oct 2026 14:27:41 -0700 (PDT) Received: from debian.. ([2001:41d0:303:db6b::]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1843cb261sm20466395e9.3.2026.10.07.14.27.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 07 Oct 2026 14:27:41 -0700 (PDT) From: Tristan Madani To: Zhu Yanjun , Jason Gunthorpe , Leon Romanovsky Cc: linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Moni Shoua , Tristan Madani Subject: [PATCH v3 2/2] RDMA/rxe: copy send WQE to kernel buffer in completer path Date: Wed, 7 Oct 2026 21:27:37 +0000 Message-ID: <20261007212737.1989004-3-tristmd@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261007212737.1989004-1-tristmd@gmail.com> References: <20261007212737.1989004-1-tristmd@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Tristan Madani The rxe completer processes send Work Queue Entries (WQEs) directly from the mmap'd shared send queue without copying them to kernel memory. Userspace can modify WQE fields (num_sge, opcode, PSN values, DMA state) while the completer is processing them, leading to inconsistent decisions in check_psn() and check_ack(), and potential out-of-bounds access in copy_data() via a corrupted dma.num_sge. This is the completer-path counterpart to the previous commit which fixed the requester path. Fix by copying the WQE to a kernel-private buffer in get_wqe() before processing. The local copy is reused across multi-packet operations (e.g. RDMA READ responses) when the WQE state is unchanged, preserving DMA progress across completer invocations. The copy is refreshed when the state changes (via smp_load_acquire pairing with the requester smp_store_release) to ensure PSN and other fields are consistent. Field updates (status, has_rd_atomic) are written back to the shared queue using WRITE_ONCE() before advancing the consumer pointer, so userspace observes consistent completion values. Fixes: 8700e3e7c485 ("Soft RoCE driver") Cc: stable@vger.kernel.org Signed-off-by: Tristan Madani --- drivers/infiniband/sw/rxe/rxe_comp.c | 54 ++++++++++++++++++++++++++- drivers/infiniband/sw/rxe/rxe_verbs.h | 6 +++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c index 1390e861bd1d7..f57c4396c28cb 100644 --- a/drivers/infiniband/sw/rxe/rxe_comp.c +++ b/drivers/infiniband/sw/rxe/rxe_comp.c @@ -88,6 +88,18 @@ static inline unsigned long rnrnak_jiffies(u8 timeout) usecs_to_jiffies(rnrnak_usec[timeout]), 1); } +static void rxe_comp_writeback_wqe(struct rxe_qp *qp) +{ + struct rxe_send_wqe *shared = qp->comp.shared_wqe; + struct rxe_send_wqe *local = &qp->comp.comp_wqe.wqe; + + if (!qp->comp.comp_wqe_valid || !shared) + return; + + WRITE_ONCE(shared->status, local->status); + WRITE_ONCE(shared->has_rd_atomic, local->has_rd_atomic); +} + static enum ib_wc_opcode wr_to_wc_opcode(enum ib_wr_opcode opcode) { switch (opcode) { @@ -142,17 +154,52 @@ static inline enum comp_state get_wqe(struct rxe_qp *qp, struct rxe_send_wqe **wqe_p) { struct rxe_send_wqe *wqe; + u32 state; + unsigned int num_sge; /* we come here whether or not we found a response packet to see if * there are any posted WQEs */ wqe = queue_head(qp->sq.queue, QUEUE_TYPE_FROM_CLIENT); - *wqe_p = wqe; /* no WQE or requester has not started it yet */ - if (!wqe || wqe->state == wqe_state_posted) + if (!wqe) { + *wqe_p = NULL; return pkt ? COMPST_DONE : COMPST_EXIT; + } + /* Pairs with smp_store_release() in rxe_req_writeback_wqe() */ + state = smp_load_acquire(&wqe->state); + if (state == wqe_state_posted) { + *wqe_p = wqe; + return pkt ? COMPST_DONE : COMPST_EXIT; + } + + /* Reuse existing local copy if still processing same WQE + * with unchanged state (preserves DMA progress for multi-packet ops) + */ + if (qp->comp.comp_wqe_valid && qp->comp.shared_wqe == wqe && + qp->comp.comp_wqe.wqe.state == state) { + wqe = &qp->comp.comp_wqe.wqe; + *wqe_p = wqe; + goto check_state; + } + + /* Copy shared WQE to kernel-private buffer */ + num_sge = wqe->dma.num_sge; + if (unlikely(num_sge > RXE_MAX_SGE)) + num_sge = RXE_MAX_SGE; + + qp->comp.shared_wqe = wqe; + memcpy(&qp->comp.comp_wqe.wqe, wqe, + sizeof(*wqe) + num_sge * sizeof(struct rxe_sge)); + qp->comp.comp_wqe_valid = true; + qp->comp.comp_wqe.wqe.dma.num_sge = num_sge; + + wqe = &qp->comp.comp_wqe.wqe; + *wqe_p = wqe; + +check_state: /* WQE does not require an ack */ if (wqe->state == wqe_state_done) return COMPST_COMP_WQE; @@ -454,6 +501,9 @@ static void do_complete(struct rxe_qp *qp, struct rxe_send_wqe *wqe) if (post) make_send_cqe(qp, wqe, &cqe); + rxe_comp_writeback_wqe(qp); + qp->comp.comp_wqe_valid = false; + queue_advance_consumer(qp->sq.queue, QUEUE_TYPE_FROM_CLIENT); if (post) diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index a22dfc6e5ae3c..6205dbc29dff6 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -130,6 +130,12 @@ struct rxe_comp_info { int started_retry; u32 retry_cnt; u32 rnr_retry; + struct rxe_send_wqe *shared_wqe; + bool comp_wqe_valid; + struct { + struct rxe_send_wqe wqe; + struct ib_sge sge[RXE_MAX_SGE]; + } comp_wqe; }; /* responder states */ -- 2.47.3