git: 5f3a2b364ea5 - main - ufshci: abort submission when payload DMA mapping fails

Jaeyoon Choi <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a7937f4.1e7cb.5be124b9__20746.2218053237$1786329102$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by jaeyoon:

URL: https://cgit.FreeBSD.org/src/commit/?id=5f3a2b364ea51ea05daa4399693bda2021e39434

commit 5f3a2b364ea51ea05daa4399693bda2021e39434
Author:     Jaeyoon Choi <[email protected]>
AuthorDate: 2026-08-10 01:31:43 +0000
Commit:     Jaeyoon Choi <[email protected]>
CommitDate: 2026-08-10 02:28:46 +0000

    ufshci: abort submission when payload DMA mapping fails
    
    When bus_dmamap_load_mem() failed, ufshci_req_queue_prepare_prdt()
    manually completed and released the tracker, but its caller kept going:
    it built the UTRD, set the slot back to SCHEDULED, and rang the
    doorbell for a tracker whose request had already been freed. Return the
    mapping error and stop the submission so the released tracker is not
    resurrected.
    
    Sponsored by:           Samsung Electronics
    Reviewed by:            imp (mentor)
    Differential Revision:  https://reviews.freebsd.org/D58653
---
 sys/dev/ufshci/ufshci_req_queue.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/sys/dev/ufshci/ufshci_req_queue.c b/sys/dev/ufshci/ufshci_req_queue.c
index 4c82b79d0e26..395801274f0e 100644
--- a/sys/dev/ufshci/ufshci_req_queue.c
+++ b/sys/dev/ufshci/ufshci_req_queue.c
@@ -371,7 +371,7 @@ ufshci_payload_map(void *arg, bus_dma_segment_t *seg, int nseg, int error)
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 }
 
-static void
+static int
 ufshci_req_queue_prepare_prdt(struct ufshci_tracker *tr)
 {
 	struct ufshci_request *req = tr->req;
@@ -403,6 +403,8 @@ ufshci_req_queue_prepare_prdt(struct ufshci_tracker *tr)
 		    UFSHCI_RESPONSE_CODE_GENERAL_FAILURE);
 		mtx_lock(&tr->hwq->qlock);
 	}
+
+	return (error);
 }
 
 static void
@@ -716,9 +718,15 @@ ufshci_req_queue_submit_tracker(struct ufshci_req_queue *req_queue,
 		memcpy(tr->ucd, &req->request_upiu, request_len);
 		memset((uint8_t *)tr->ucd + response_off, 0, response_len);
 
-		/* Prepare PRDT */
-		if (req->payload_valid)
-			ufshci_req_queue_prepare_prdt(tr);
+		/*
+		 * Prepare PRDT. If the payload could not be mapped, the
+		 * tracker has already been completed and released by the
+		 * manual completion path, so the descriptor must not be
+		 * built and the doorbell must not be rung.
+		 */
+		if (req->payload_valid &&
+		    ufshci_req_queue_prepare_prdt(tr) != 0)
+			return;
 
 		/* Prepare UTP Transfer Request Descriptor. */
 		ucd_paddr = tr->ucd_bus_addr;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.