From nobody Sat Feb 7 05:48:54 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1766411459; cv=none; d=zohomail.com; s=zohoarc; b=hDxI6uUeb79NcTaZbHzlH04U5heq9+b/tnrZbsgfJYNyXUvOAz14cAJGhbGHhZFBLaSqweAXyoRyjNr130tzXDsLobVnrMQsRU0hW8xrv7RVX/DjRDT97N8I9NMxv8/axhfepEB24grejMR9i16gR47FawyPPqmcy/8OLjsrQyE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1766411459; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=uoZl1vVLVmw3D/1aiTw3Zwq7YSLi+XNae1jflmtjDqA=; b=mCYtk261nen93miJVgIkAw5B4Mm4nllBIGHZk+jmiMKHj2eXJ3eCEuFsBe5zxjGcPwV9T3Gr576fjHhXQw95CXneHCD8rSsCibuC2ndeOEAOP+gxoVWaa9aWLDH9h2bj6kMWlXY7lJKBrXpgNTj5nfVN3Y3HHQlB+NMKe9ABzTQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1766411459533984.9754622638342; Mon, 22 Dec 2025 05:50:59 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vXgIo-0004VO-Cw; Mon, 22 Dec 2025 08:50:22 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vXf99-00049V-ES for qemu-devel@nongnu.org; Mon, 22 Dec 2025 07:36:20 -0500 Received: from mgamail.intel.com ([192.198.163.17]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vXf97-0005KG-Fl for qemu-devel@nongnu.org; Mon, 22 Dec 2025 07:36:19 -0500 Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Dec 2025 04:36:15 -0800 Received: from unknown (HELO ilevi-mobl.intel.com) ([10.13.220.47]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Dec 2025 04:36:14 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1766406977; x=1797942977; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=A+FK9MGZIaeUuGS7ojIi8kBaRCcnKXus10ZgTHWD2xI=; b=U8ntozwk9g5gCMl+dxaaYdTcdrqETgwTnbIM+fzrZgmJvXTMDSViLzFS hcbxOCbQfHSbx1eHqVcE8081fCKiBkFdU7ywXy82T/Df40lCq8imOEEzs E3hzzWR+Jbz7W10XdMRN7hvlqUXFlz+GyL+ddaGmbo20n5JGurgR+WRmO 8KU1asxTItv3ZG4q1H3o7DKgml6uq7yTuEreZUy6/TLin47owIRaCBzNF 2jSWqspgJ+HO/NEm6d3K6jTMKkIOIq8687ZAR0Zo7OTK4r039xcV6PuuP vceU2jelwfN4KNw+oLuSSr462m9mvte2zZ3HWzNIkDPhS1dflBBQMhOCe A==; X-CSE-ConnectionGUID: rjpwhFzoRSWb3K5vYQrU7A== X-CSE-MsgGUID: XXZNRqtAT/6EZ0n7+jYOaA== X-IronPort-AV: E=McAfee;i="6800,10657,11649"; a="68142500" X-IronPort-AV: E=Sophos;i="6.21,168,1763452800"; d="scan'208";a="68142500" X-CSE-ConnectionGUID: pcQhGzapTT+ssxfJ3q5ILA== X-CSE-MsgGUID: n0B8aS1lQqiOJ2yUqQguKg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,168,1763452800"; d="scan'208";a="200408070" From: Ilia Levi To: qemu-devel@nongnu.org Cc: ilia.levi@intel.com, jeuk20.kim@samsung.com, farosas@suse.de, lvivier@redhat.com, pbonzini@redhat.com Subject: [PATCH 1/2] hw/ufs: Fix mcq completion queue wraparound Date: Mon, 22 Dec 2025 14:35:58 +0200 Message-ID: <20251222123559.3387-2-ilia.levi@intel.com> X-Mailer: git-send-email 2.49.1 In-Reply-To: <20251222123559.3387-1-ilia.levi@intel.com> References: <20251222123559.3387-1-ilia.levi@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=192.198.163.17; envelope-from=ilia.levi@intel.com; helo=mgamail.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Mon, 22 Dec 2025 08:50:04 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @intel.com) X-ZM-MESSAGEID: 1766411461144158500 Content-Type: text/plain; charset="utf-8" Currently, ufs_mcq_process_cq() writes to the CQ without checking whether there is available space. This can cause CQ entries to be discarded and overwritten. The solution is to stop writing when CQ is full and exert backpressure on the affected SQs. This is similar to how NVMe CQs operate. Signed-off-by: Ilia Levi Reviewed-by: Jeuk Kim --- hw/ufs/ufs.c | 20 +++++++++++++++++++- hw/ufs/ufs.h | 9 +++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c index 0577747f46..671b851de7 100644 --- a/hw/ufs/ufs.c +++ b/hw/ufs/ufs.c @@ -446,6 +446,10 @@ static void ufs_mcq_process_cq(void *opaque) =20 QTAILQ_FOREACH_SAFE(req, &cq->req_list, entry, next) { + if (ufs_mcq_cq_full(u, cq->cqid)) { + break; + } + ufs_dma_write_rsp_upiu(req); =20 req->cqe.utp_addr =3D @@ -468,6 +472,12 @@ static void ufs_mcq_process_cq(void *opaque) tail =3D (tail + sizeof(req->cqe)) % (cq->size * sizeof(req->cqe)); ufs_mcq_update_cq_tail(u, cq->cqid, tail); =20 + if (QTAILQ_EMPTY(&req->sq->req_list) && + !ufs_mcq_sq_empty(u, req->sq->sqid)) { + /* Dequeueing from SQ was blocked due to lack of free requests= */ + qemu_bh_schedule(req->sq->bh); + } + ufs_clear_req(req); QTAILQ_INSERT_TAIL(&req->sq->req_list, req, entry); } @@ -777,10 +787,18 @@ static void ufs_write_mcq_op_reg(UfsHc *u, hwaddr off= set, uint32_t data, } opr->sq.tp =3D data; break; - case offsetof(UfsMcqOpReg, cq.hp): + case offsetof(UfsMcqOpReg, cq.hp): { + UfsCq *cq =3D u->cq[qid]; + + if (ufs_mcq_cq_full(u, qid) && !QTAILQ_EMPTY(&cq->req_list)) { + /* Enqueueing to CQ was blocked because it was full */ + qemu_bh_schedule(cq->bh); + } + opr->cq.hp =3D data; ufs_mcq_update_cq_head(u, qid, data); break; + } case offsetof(UfsMcqOpReg, cq_int.is): opr->cq_int.is &=3D ~data; break; diff --git a/hw/ufs/ufs.h b/hw/ufs/ufs.h index 3799d97f30..13d964c5ae 100644 --- a/hw/ufs/ufs.h +++ b/hw/ufs/ufs.h @@ -200,6 +200,15 @@ static inline bool ufs_mcq_cq_empty(UfsHc *u, uint32_t= qid) return ufs_mcq_cq_tail(u, qid) =3D=3D ufs_mcq_cq_head(u, qid); } =20 +static inline bool ufs_mcq_cq_full(UfsHc *u, uint32_t qid) +{ + uint32_t tail =3D ufs_mcq_cq_tail(u, qid); + uint16_t cq_size =3D u->cq[qid]->size; + + tail =3D (tail + sizeof(UfsCqEntry)) % (sizeof(UfsCqEntry) * cq_size); + return tail =3D=3D ufs_mcq_cq_head(u, qid); +} + #define TYPE_UFS "ufs" #define UFS(obj) OBJECT_CHECK(UfsHc, (obj), TYPE_UFS) =20 --=20 2.49.1 From nobody Sat Feb 7 05:48:54 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1766411456; cv=none; d=zohomail.com; s=zohoarc; b=Zc5Dl+sXafjMLLHFi8/c6thab93nFeIbs/RnR3+14v+cTZevJ3Nhnz/ZQ9spnXFHqiP3KWKaXsgOI8BP0112qN73qN+gq0aDPm0mY6pCKxLpNzx7ZFNGsyZmtz+7ECeUmd6pIqIdfyGcZq9W1k/Kg0VWw9SUzIoz72N5CA4W3dY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1766411456; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=kmlGcvqgp3SF/EvgRYaKUl/K/7ooZS7H7IjSyZb82NI=; b=ArohaR9Qix/f7TQC2hKOlQ3f6xItB5wa8qOluI92TarXqX6/l7p8uXFsq+wrXoFwDpy6s0BUUcmKfjItDDuk4DJJ1u91N85JZ0RcvTDNMCsrO6UeHAJsNKd5SaHT1oWJgHOjnqe9Bm9roxvh+3aQ/oKe7C1MR7Fx2oYwc6Y6uLY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1766411455228905.1122961737774; Mon, 22 Dec 2025 05:50:55 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vXgIz-0004a3-EL; Mon, 22 Dec 2025 08:50:36 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vXf9B-00049m-F6 for qemu-devel@nongnu.org; Mon, 22 Dec 2025 07:36:26 -0500 Received: from mgamail.intel.com ([192.198.163.17]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vXf99-0005Jv-NO for qemu-devel@nongnu.org; Mon, 22 Dec 2025 07:36:21 -0500 Received: from fmviesa010.fm.intel.com ([10.60.135.150]) by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Dec 2025 04:36:19 -0800 Received: from unknown (HELO ilevi-mobl.intel.com) ([10.13.220.47]) by fmviesa010-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Dec 2025 04:36:17 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1766406979; x=1797942979; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HrWlpf7UH0Y4M2UvrzFMqrHquRK6NcZu5BxapdR0Bew=; b=D0q1xfrZQiKUajmyyJj1JjUeyIdCnwsg2xvD1q/t5S6IAywEgscTklJO DjFEULOoyuJRUdIIAdSjNGc+5+dCZY+2GjmQCUOjSfqQiSRFC3jdmQVMC 3pFxqB4usF4/Q/0nTrQ48hS1OBq1/cq/1PA4Sd/E8DKprzipF+Lx/599x 0COkNJQmfep/YN352ztnDM8k9yZvDfGY4h/M/bkp+AzOyK1wtYqn6JjxM 4V9YVfZVTt73ruoFacZrtc/Eefa7BPgnw9J4pmWAolJppiOcTG+2F5Vak Cg36+ABGCXhHTexmHrebqXvfX7HmAXxzQaOcqaHOA9rv30njW4pedHxbw w==; X-CSE-ConnectionGUID: 5MfsW4f+RdyOLw443ynQjg== X-CSE-MsgGUID: PMdRDkJKTG2YmEesWbarXw== X-IronPort-AV: E=McAfee;i="6800,10657,11649"; a="68142504" X-IronPort-AV: E=Sophos;i="6.21,168,1763452800"; d="scan'208";a="68142504" X-CSE-ConnectionGUID: QiAzCzhbT2OYtpQD18gBZg== X-CSE-MsgGUID: g04tMp7RTXytzRIfSPZKcg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,168,1763452800"; d="scan'208";a="200408080" From: Ilia Levi To: qemu-devel@nongnu.org Cc: ilia.levi@intel.com, jeuk20.kim@samsung.com, farosas@suse.de, lvivier@redhat.com, pbonzini@redhat.com Subject: [PATCH 2/2] tests/qtest/ufs-test: Add test for mcq completion queue wraparound Date: Mon, 22 Dec 2025 14:35:59 +0200 Message-ID: <20251222123559.3387-3-ilia.levi@intel.com> X-Mailer: git-send-email 2.49.1 In-Reply-To: <20251222123559.3387-1-ilia.levi@intel.com> References: <20251222123559.3387-1-ilia.levi@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=192.198.163.17; envelope-from=ilia.levi@intel.com; helo=mgamail.intel.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Mon, 22 Dec 2025 08:50:03 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @intel.com) X-ZM-MESSAGEID: 1766411457323158500 Content-Type: text/plain; charset="utf-8" Added a test that sends 32 NOP Out commands asynchronously. Since the CQ has 31 entries by default, this tests the scenario where CQ processing needs to wait for space to become available. Additionally, added two minor fixes to existing tests: * advance CQ head after reading from CQ * initialize command descriptor slots bitmap in ufs_init() Signed-off-by: Ilia Levi Acked-by: Fabiano Rosas Reviewed-by: Jeuk Kim --- tests/qtest/ufs-test.c | 125 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/tests/qtest/ufs-test.c b/tests/qtest/ufs-test.c index 4867ccf08a..a5f5243886 100644 --- a/tests/qtest/ufs-test.c +++ b/tests/qtest/ufs-test.c @@ -166,6 +166,7 @@ __ufs_send_transfer_request_mcq(QUfs *ufs, uint8_t lun, cqhp =3D ufs_rreg(ufs, ufs->cqdao[TEST_QID]); cqentry_addr =3D ufs->cqlba[TEST_QID] + cqhp; qtest_memread(ufs->dev.bus->qts, cqentry_addr, &cqentry, sizeof(cqentr= y)); + cqhp =3D (cqhp + sizeof(UfsCqEntry)) % (QUEUE_SIZE * sizeof(UfsCqEntry= )); ufs_wreg(ufs, ufs->cqdao[TEST_QID], cqhp); =20 return cqentry.status; @@ -208,6 +209,80 @@ static enum UtpOcsCodes ufs_send_nop_out(QUfs *ufs, Ut= pUpiuRsp *rsp_out) return ret; } =20 +static bool ufs_mcq_sq_has_space(QUfs *ufs) +{ + uint32_t sqhp =3D ufs_rreg(ufs, ufs->sqdao[TEST_QID]); + uint32_t sqtp =3D ufs_rreg(ufs, ufs->sqdao[TEST_QID] + 0x4); + uint32_t next_sqtp =3D (sqtp + sizeof(UfsSqEntry)) % + (QUEUE_SIZE * sizeof(UfsSqEntry)); + return next_sqtp !=3D sqhp; +} + +static void __ufs_send_transfer_request_mcq_async(QUfs *ufs, uint8_t lun, + const UtpTransferReqDesc *utrd) +{ + uint32_t sqtp; + uint64_t utrd_addr; + + /* Wait for SQ space */ + while (!ufs_mcq_sq_has_space(ufs)) { + qtest_clock_step(ufs->dev.bus->qts, 100); + } + + sqtp =3D ufs_rreg(ufs, ufs->sqdao[TEST_QID] + 0x4); + utrd_addr =3D ufs->sqlba[TEST_QID] + sqtp; + qtest_memwrite(ufs->dev.bus->qts, utrd_addr, utrd, sizeof(*utrd)); + sqtp =3D (sqtp + sizeof(UfsSqEntry)) % (QUEUE_SIZE * sizeof(UfsSqEntry= )); + ufs_wreg(ufs, ufs->sqdao[TEST_QID] + 0x4, sqtp); +} + +static int ufs_mcq_send_nop_out_async(QUfs *ufs) +{ + int cmd_desc_slot =3D alloc_cmd_desc_slot(ufs); + uint64_t req_upiu_addr =3D + ufs->cmd_desc_addr + cmd_desc_slot * UTP_COMMAND_DESCRIPTOR_SIZE; + + /* Build up request upiu */ + UtpUpiuReq req_upiu =3D { 0 }; + req_upiu.header.trans_type =3D UFS_UPIU_TRANSACTION_NOP_OUT; + req_upiu.header.task_tag =3D cmd_desc_slot; + qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu, + sizeof(req_upiu)); + + /* Build up utp transfer request descriptor */ + UtpTransferReqDesc utrd =3D + ufs_build_req_utrd(req_upiu_addr, UFS_UTP_NO_DATA_TRANSFER, 0); + + /* Send Transfer Request */ + __ufs_send_transfer_request_mcq_async(ufs, 0, &utrd); + + return cmd_desc_slot; +} + +static int ufs_mcq_poll_cq(QUfs *ufs, UfsCqEntry *cqe, uint16_t n_cqe) +{ + uint32_t cqhp, cqtp; + uint64_t cqe_addr; + int ix =3D 0; + + cqhp =3D ufs_rreg(ufs, ufs->cqdao[TEST_QID]); + cqtp =3D ufs_rreg(ufs, ufs->cqdao[TEST_QID] + 0x4); + + while (cqhp !=3D cqtp && ix < n_cqe) { + /* read completion entry */ + cqe_addr =3D ufs->cqlba[TEST_QID] + cqhp; + qtest_memread(ufs->dev.bus->qts, cqe_addr, &cqe[ix], sizeof(cqe[ix= ])); + + /* advance completion queue head pointer */ + cqhp =3D (cqhp + sizeof(UfsCqEntry)) % (QUEUE_SIZE * sizeof(UfsCqE= ntry)); + ix++; + } + + ufs_wreg(ufs, ufs->cqdao[TEST_QID], cqhp); + + return ix; +} + static enum UtpOcsCodes ufs_send_query(QUfs *ufs, uint8_t query_function, uint8_t query_opcode, uint8_t idn, uint8_t index, uint8_t selector, @@ -416,6 +491,7 @@ static void ufs_init(QUfs *ufs, QGuestAllocator *alloc) ufs_wreg(ufs, A_UTRIACR, 0); =20 /* Enable transfer request */ + bitmap_zero(ufs->cmd_desc_bitmap, UFS_MAX_CMD_DESC); ufs->cmd_desc_addr =3D guest_alloc(alloc, UFS_MAX_CMD_DESC * UTP_COMMAND_DESCRIPTOR_SIZE); ufs->data_buffer_addr =3D @@ -679,6 +755,53 @@ static void ufstest_read_write(void *obj, void *data, = QGuestAllocator *alloc) ufs_exit(ufs, alloc); } =20 +static void ufstest_mcq_cq_wraparound(void *obj, void *data, + QGuestAllocator *alloc) +{ + QUfs *ufs =3D obj; + UfsCqEntry cqe[QUEUE_SIZE]; + const int num_requests =3D QUEUE_SIZE; + int i, completed =3D 0; + + ufs_init(ufs, alloc); + + /* Ensure MCQ is supported */ + g_assert_true(ufs->support_mcq); + + for (i =3D 0; i < num_requests; ++i) { + ufs_mcq_send_nop_out_async(ufs); + } + + while (completed !=3D num_requests) { + int n_cqe =3D ufs_mcq_poll_cq(ufs, cqe, ARRAY_SIZE(cqe)); + if (!n_cqe) { + break; + } + + for (i =3D 0; i < n_cqe; ++i) { + uint64_t ucdba; + uint64_t rsp_upiu_addr; + UtpUpiuRsp rsp_upiu; + uint8_t tag; + + g_assert_cmpuint(cqe[i].status, =3D=3D, UFS_OCS_SUCCESS); + + ucdba =3D le64_to_cpu(cqe[i].utp_addr) & MAKE_64BIT_MASK(7, 57= ); + rsp_upiu_addr =3D ucdba + UTP_RESPONSE_UPIU_OFFSET; + qtest_memread(ufs->dev.bus->qts, rsp_upiu_addr, &rsp_upiu, + sizeof(rsp_upiu)); + + tag =3D rsp_upiu.header.task_tag; + release_cmd_desc_slot(ufs, tag); + } + + completed +=3D n_cqe; + } + + g_assert_cmpint(completed, =3D=3D, num_requests); + ufs_exit(ufs, alloc); +} + static void ufstest_query_flag_request(void *obj, void *data, QGuestAllocator *alloc) { @@ -1129,6 +1252,8 @@ static void ufs_register_nodes(void) qos_add_test("init", "ufs", ufstest_init, NULL); qos_add_test("legacy-read-write", "ufs", ufstest_read_write, &io_test_= opts); qos_add_test("mcq-read-write", "ufs", ufstest_read_write, &mcq_test_op= ts); + qos_add_test("mcq-cq-wraparound", "ufs", ufstest_mcq_cq_wraparound, + &mcq_test_opts); qos_add_test("query-flag", "ufs", ufstest_query_flag_request, &io_test_opts); qos_add_test("query-attribute", "ufs", ufstest_query_attr_request, --=20 2.49.1