git: 266ce89fc231 - main - ufshci: read UIC command results while holding the lock

Jaeyoon Choi <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a793802.1e233.29cc2259__44458.3810329036$1786329250$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by jaeyoon:

URL: https://cgit.FreeBSD.org/src/commit/?id=266ce89fc231d58431293cf5b77e0854440aa13d

commit 266ce89fc231d58431293cf5b77e0854440aa13d
Author:     Jaeyoon Choi <[email protected]>
AuthorDate: 2026-08-10 01:48:41 +0000
Commit:     Jaeyoon Choi <[email protected]>
CommitDate: 2026-08-10 02:28:52 +0000

    ufshci: read UIC command results while holding the lock
    
    The UIC result registers (UICCMDARG2/3) are only valid between a
    command's completion and the next command's submission. They were read
    after uic_cmd_lock was dropped, so a concurrent UIC submitter could
    overwrite them in between. Read them into locals before releasing the
    lock.
    
    Also mask the generic error code to its [7:0] field when checking it,
    so unrelated bits in UICCMDARG2 (such as the attribute set type echoed
    for DME_SET) cannot be mistaken for an error.
    
    Sponsored by:           Samsung Electronics
    Reviewed by:            imp (mentor)
    Differential Revision:  https://reviews.freebsd.org/D58667
---
 sys/dev/ufshci/ufshci_uic_cmd.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/sys/dev/ufshci/ufshci_uic_cmd.c b/sys/dev/ufshci/ufshci_uic_cmd.c
index 03ea8b2ba9f1..45ded2a120c6 100644
--- a/sys/dev/ufshci/ufshci_uic_cmd.c
+++ b/sys/dev/ufshci/ufshci_uic_cmd.c
@@ -170,7 +170,7 @@ ufshci_uic_send_cmd(struct ufshci_controller *ctrlr,
     struct ufshci_uic_cmd *uic_cmd, uint32_t *return_value)
 {
 	int error;
-	uint32_t config_result_code;
+	uint32_t config_result_code, result_value;
 
 	mtx_lock(&ctrlr->uic_cmd_lock);
 
@@ -188,12 +188,18 @@ ufshci_uic_send_cmd(struct ufshci_controller *ctrlr,
 
 	error = ufshci_uic_wait_cmd(ctrlr, uic_cmd);
 
+	/* The result registers stay valid only until the next command. */
+	if (error == 0) {
+		config_result_code = UFSHCIV(UFSHCI_UICCMDARG2_REG_ERROR_CODE,
+		    ufshci_mmio_read_4(ctrlr, ucmdarg2));
+		result_value = ufshci_mmio_read_4(ctrlr, ucmdarg3);
+	}
+
 	mtx_unlock(&ctrlr->uic_cmd_lock);
 
 	if (error)
 		return (ENXIO);
 
-	config_result_code = ufshci_mmio_read_4(ctrlr, ucmdarg2);
 	if (config_result_code) {
 		ufshci_printf(ctrlr,
 		    "Failed to send UIC command (Opcode: 0x%x"
@@ -210,7 +216,7 @@ ufshci_uic_send_cmd(struct ufshci_controller *ctrlr,
 	}
 
 	if (return_value != NULL)
-		*return_value = ufshci_mmio_read_4(ctrlr, ucmdarg3);
+		*return_value = result_value;
 
 	return (0);
 }
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.