From nobody Sun Jul 26 11:54:37 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=posteo.net ARC-Seal: i=1; a=rsa-sha256; t=1782820407; cv=none; d=zohomail.com; s=zohoarc; b=UcpIq7kajG4Ujkyi9qtUgkQVGcWcKcKnkBtZtqQMTJ27JOXGv3RMfE8dkfg+jn02wmnN8PJYdxakA/FFlKuqO/zUKwoNLk8AytEEcYp2N5MU66qzwQBipoTgVESsTGLipLLROJ60YEf2RB5HFWvr6c51ucyYLTS/9U1TPSmLXg4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782820407; 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=rYJ3L3PrdQEPLBIwAhso/Ek23Ts5KsX6BRcQkUxT5cI=; b=FR4dGBUdU3irxVps3ZNVKIlUsR1TiipW2IrGhHJeM/61jAx4FfyqHBBGcaEm0ZHTnvAnjWaxwPWXpHy5bdhMkpv+inFEtzAQVOpcAVooG8U1xfeFUuM3x47/2Ci0lnfmIs4Bz6K4yVtoy0fv6UdUQqjriV2AOSz96PgJfkXKsWg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1782820407389732.5339440901389; Tue, 30 Jun 2026 04:53:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1weX1B-0002Ud-PU; Tue, 30 Jun 2026 07:52:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1weX18-0002SF-9a for qemu-devel@nongnu.org; Tue, 30 Jun 2026 07:52:42 -0400 Received: from mout01.posteo.de ([185.67.36.65]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1weX13-0001LU-0d for qemu-devel@nongnu.org; Tue, 30 Jun 2026 07:52:40 -0400 Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id 509B7240029 for ; Tue, 30 Jun 2026 13:52:34 +0200 (CEST) Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4gqM2m4Mspz6v11; Tue, 30 Jun 2026 13:52:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.net; s=2017; t=1782820354; bh=rYJ3L3PrdQEPLBIwAhso/Ek23Ts5KsX6BRcQkUxT5cI=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version: Content-Transfer-Encoding:From; b=XTdq9zo1vrCmE+vw+A+iIbpY+NcoaZbjp+K+x1/G893K+2rkproGYuYAsDe4iShaH l6i9A7zhyANPuk27rQj6ZruRvbrMMWDqc/x1honCxYu61/r3mTegVOgwfXmnoGyr7A AHBXCB/CbdL+KHKeUQci5SSrDtPziLsKaEIy7A4YUcUSEbzljt/Keq/V4+59elRxy+ fR2CDsh0oig2UKa4SdwOW/fPIvHFjBdWMYwnq84606YPfhl64Cvv3YDimHTNVyjd4f kp71AFWKBeNfEU3xyD8YwvdOg9Thcl/6lXDlvCCDVx9HFadIU7A2OCXvE5NIJ5DFad c0MErtf0S0iNQ== From: Mateusz Nowicki To: qemu-devel@nongnu.org Cc: Mateusz Nowicki , Klaus Jensen , "Dr . David Alan Gilbert" , Markus Armbruster , Keith Busch , Jesper Devantier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Zhao Liu , Eric Blake , qemu-block@nongnu.org Subject: [PATCH v4 1/2] hw/nvme: add 'info nvme' HMP command Date: Tue, 30 Jun 2026 11:52:33 +0000 Message-ID: In-Reply-To: References: 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=lists1p.gnu.org; Received-SPF: pass client-ip=185.67.36.65; envelope-from=mateusz.nowicki@posteo.net; helo=mout01.posteo.de 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, 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_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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 @posteo.net) X-ZM-MESSAGEID: 1782820410006158500 Content-Type: text/plain; charset="utf-8" Add an 'info nvme' HMP command for inspecting emulated NVMe controllers from the QEMU monitor. For each NVMe controller in the QOM tree the command prints: - PCI BDF, vendor/device ID and BAR0 base address; - Identify Controller fields visible to the host driver: SN, MN, FR and CNTLID; - the CC, CSTS and AQA registers (raw 32-bit values); - the number of admin and active I/O submission/completion queues. Useful when debugging the Linux NVMe driver against the QEMU emulation without attaching gdb to the QEMU process. Example: (qemu) info nvme /machine/peripheral-anon/device[0] PCI: BDF 00:04.0 VID=3D8086 DID=3D5845 BAR0=3D0x00000000feb50000 ID: SN=3DNVME0001 MN=3DQEMU NVMe Ctrl FR=3D... CNTLID=3D0x0000 CC: 0x00460001 CSTS: 0x00000001 AQA: 0x001f001f Queues: 1 admin + 4 IO SQ / 4 IO CQ Signed-off-by: Mateusz Nowicki Acked-by: Dr. David Alan Gilbert Acked-by: Markus Armbruster --- hmp-commands-info.hx | 13 ++++++++ hw/nvme/meson.build | 4 ++- hw/nvme/monitor-stub.c | 15 +++++++++ hw/nvme/monitor.c | 76 ++++++++++++++++++++++++++++++++++++++++++ qapi/machine.json | 17 ++++++++++ 5 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 hw/nvme/monitor-stub.c create mode 100644 hw/nvme/monitor.c diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index 82134eb6c2..b984691c3c 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -340,6 +340,19 @@ SRST Show guest USB devices. ERST =20 + { + .name =3D "nvme", + .args_type =3D "", + .params =3D "", + .help =3D "show emulated NVMe controllers", + .cmd_info_hrt =3D qmp_x_query_nvme, + }, + +SRST + ``info nvme`` + Show emulated NVMe controllers. +ERST + { .name =3D "usbhost", .args_type =3D "", diff --git a/hw/nvme/meson.build b/hw/nvme/meson.build index 7d5caa53c2..99f336399e 100644 --- a/hw/nvme/meson.build +++ b/hw/nvme/meson.build @@ -1 +1,3 @@ -system_ss.add(when: 'CONFIG_NVME_PCI', if_true: files('ctrl.c', 'dif.c', '= ns.c', 'subsys.c', 'nguid.c')) \ No newline at end of file +system_ss.add(when: 'CONFIG_NVME_PCI', + if_true: files('ctrl.c', 'dif.c', 'monitor.c', 'nguid.c', 'n= s.c', 'subsys.c'), + if_false: files('monitor-stub.c')) diff --git a/hw/nvme/monitor-stub.c b/hw/nvme/monitor-stub.c new file mode 100644 index 0000000000..5eb9f04c8d --- /dev/null +++ b/hw/nvme/monitor-stub.c @@ -0,0 +1,15 @@ +/* + * QEMU NVMe Controller monitor command stubs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qapi/qapi-commands-machine.h" + +HumanReadableText *qmp_x_query_nvme(Error **errp) +{ + error_setg(errp, "NVMe support is not compiled in"); + return NULL; +} diff --git a/hw/nvme/monitor.c b/hw/nvme/monitor.c new file mode 100644 index 0000000000..95a6754437 --- /dev/null +++ b/hw/nvme/monitor.c @@ -0,0 +1,76 @@ +/* + * QEMU NVMe Controller monitor commands + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qapi/qapi-commands-machine.h" +#include "qapi/type-helpers.h" +#include "hw/pci/pci.h" + +#include "nvme.h" + +static int collect_one(Object *obj, void *opaque) +{ + GString *buf =3D opaque; + NvmeCtrl *n; + PCIDevice *pci; + pcibus_t bar0; + unsigned io_sq =3D 0, io_cq =3D 0; + + if (!object_dynamic_cast(obj, TYPE_NVME)) { + return 0; + } + n =3D NVME(obj); + pci =3D PCI_DEVICE(n); + bar0 =3D pci_get_bar_addr(pci, 0); + + for (unsigned i =3D 1; i <=3D n->params.max_ioqpairs; i++) { + if (n->sq && n->sq[i]) { + io_sq++; + } + if (n->cq && n->cq[i]) { + io_cq++; + } + } + + g_string_append_printf(buf, "%s\n", object_get_canonical_path(obj)); + g_string_append_printf(buf, + " PCI: BDF %02x:%02x.%x VID=3D%04x DID=3D%04x ", + pci_dev_bus_num(pci), PCI_SLOT(pci->devfn), PCI_FUNC(pci->devfn), + pci_get_word(pci->config + PCI_VENDOR_ID), + pci_get_word(pci->config + PCI_DEVICE_ID)); + if (bar0 =3D=3D PCI_BAR_UNMAPPED) { + g_string_append(buf, "BAR0=3Dunmapped\n"); + } else { + g_string_append_printf(buf, "BAR0=3D0x%016" PRIx64 "\n", + (uint64_t)bar0); + } + g_string_append_printf(buf, + " ID: SN=3D%.20s MN=3D%.40s FR=3D%.8s CNTLID=3D0x%04x\n", + n->id_ctrl.sn, n->id_ctrl.mn, n->id_ctrl.fr, n->cntlid); + g_string_append_printf(buf, " CC: 0x%08x\n", + ldl_le_p(&n->bar.cc)); + g_string_append_printf(buf, " CSTS: 0x%08x\n", + ldl_le_p(&n->bar.csts)); + g_string_append_printf(buf, " AQA: 0x%08x\n", + ldl_le_p(&n->bar.aqa)); + g_string_append_printf(buf, + " Queues: 1 admin + %u IO SQ / %u IO CQ\n", io_sq, io_cq); + return 0; +} + +HumanReadableText *qmp_x_query_nvme(Error **errp) +{ + g_autoptr(GString) buf =3D g_string_new(""); + + object_child_foreach_recursive(object_get_root(), collect_one, buf); + + if (buf->len =3D=3D 0) { + g_string_append(buf, "no NVMe controllers\n"); + } + + return human_readable_text_from_str(buf); +} diff --git a/qapi/machine.json b/qapi/machine.json index 685e4e29b8..d4a589e768 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -1772,6 +1772,23 @@ 'returns': 'HumanReadableText', 'features': [ 'unstable' ] } =20 +## +# @x-query-nvme: +# +# Query state of emulated NVMe controllers. +# +# Features: +# +# @unstable: This command is meant for debugging. +# +# Returns: NVMe controller state as human-readable text +# +# Since: 11.1 +## +{ 'command': 'x-query-nvme', + 'returns': 'HumanReadableText', + 'features': [ 'unstable' ] } + ## # @SmbiosEntryPointType: # --=20 2.53.0 From nobody Sun Jul 26 11:54:37 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=posteo.net ARC-Seal: i=1; a=rsa-sha256; t=1782820428; cv=none; d=zohomail.com; s=zohoarc; b=S0rN8ItTsjjNZUvO23kMyYfJ9bT/IhMdWdlNv51G3ZmHGrQ/9oR2lRVyanaTNm8fUN60DrmjFL7QtGYf8W565h8SgRHqvQ9gY8XQeayc6zUDisng2HVxbq2OXC2dWM33ifaPZCgOeOd+VC1+UjPmVJLsQeCOb4cDMSGPjk0fgkc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782820428; 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=1a8nVCf5L0n90zM9p8EuZBcSpS2tt5IZlMv/BXN4Q4o=; b=JxrHgAKQjPVb8vaFuM4ldm/ahCPU9M1cGFr3gx96YGe94wPFPQrWjSwP0axg2foXMdNYMifXZZPWI6HxDoLvbGOFDKiBcXUi4zoEtk5P2TBbJgfaVRIRljYj1FdHJssOCQ9MYRZOjaNNuGNJWJ3p+oz4VRJR5YJFoB7xvSfMqZI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 17828204279501005.9247129602307; Tue, 30 Jun 2026 04:53:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1weX1A-0002U4-Bk; Tue, 30 Jun 2026 07:52:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1weX18-0002SI-GG for qemu-devel@nongnu.org; Tue, 30 Jun 2026 07:52:42 -0400 Received: from mout02.posteo.de ([185.67.36.66]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1weX15-0001Ld-1G for qemu-devel@nongnu.org; Tue, 30 Jun 2026 07:52:42 -0400 Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 46E1F240103 for ; Tue, 30 Jun 2026 13:52:36 +0200 (CEST) Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4gqM2n5xDlz6v0F; Tue, 30 Jun 2026 13:52:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.net; s=2017; t=1782820356; bh=1a8nVCf5L0n90zM9p8EuZBcSpS2tt5IZlMv/BXN4Q4o=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version: Content-Transfer-Encoding:From; b=o6tMlpjtZso1rgtfM3rPU+1Dd+kYSr1+R5ixJIPe9o5EMnM2KxsRxroKqyTQsk7Cs Y5qAqmCFuSv7b7aSgcGLqtYv1kANPkL35zm1/1wQXsD/abPu2gunBI5ZOPUK7/qy88 czYPwy8gV3B7XmryFxNR6HSkqdH+NYuqCcgtYCU4M98bIIHvAln7Yf1QX0+ewP29Th l2DqqRFEau3hqU7el/WZeFDWXCYY3wuHRI1JFvWbV2gjz9S1jyd6tNyFhhNi3nFMqi iY0FfY+o/mtrZLbZmVZga9jS2AQdhxfK8lk+sIJlePiHY+kgA8KKeWtS/ks0OsOI8x kzHlTXQ4nIcVg== From: Mateusz Nowicki To: qemu-devel@nongnu.org Cc: Mateusz Nowicki , Klaus Jensen , "Dr . David Alan Gilbert" , Markus Armbruster , Keith Busch , Jesper Devantier , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Zhao Liu , Eric Blake , qemu-block@nongnu.org Subject: [PATCH v4 2/2] hw/nvme: add 'info nvme-queues' HMP command Date: Tue, 30 Jun 2026 11:52:35 +0000 Message-ID: <416be273b5f007e656d2ac8ec67d817114ac5452.1782819251.git.mateusz.nowicki@posteo.net> In-Reply-To: References: 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=lists1p.gnu.org; Received-SPF: pass client-ip=185.67.36.66; envelope-from=mateusz.nowicki@posteo.net; helo=mout02.posteo.de 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, 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_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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 @posteo.net) X-ZM-MESSAGEID: 1782820429436158500 Content-Type: text/plain; charset="utf-8" Add an 'info nvme-queues' HMP command that lists, for every emulated NVMe controller, the admin SQ/CQ and every active I/O SQ/CQ. For each queue the command prints: - the ring size, head and tail indices; - the associated CQ id (for SQ) or interrupt vector (for CQ); - the queue's PRP1 (DMA base address of the ring); - the BAR0-relative doorbell offset (SQyTDBL / CQyHDBL); - the current CQ phase tag. The doorbell offsets are computed from CAP.DSTRD so they remain correct if the emulation ever exposes a non-zero stride. Useful when debugging the Linux NVMe driver against the QEMU emulation - queue setup, doorbell rings, AERs held in the admin SQ etc. - without attaching gdb to the QEMU process. Example, with the long PRP1 ring address and BAR0-relative doorbell offset replaced by '...'; phase tag column omitted for brevity: (qemu) info nvme-queues /machine/peripheral-anon/device[0] SQ 0 size=3D32 head=3D9 tail=3D9 cqid=3D0 prp1=3D... SQTD= BL=3D... CQ 0 size=3D32 head=3D8 tail=3D8 iv=3D0 prp1=3D... CQHD= BL=3D... SQ 1 size=3D1024 head=3D2 tail=3D2 cqid=3D1 prp1=3D... SQTD= BL=3D... CQ 1 size=3D1024 head=3D2 tail=3D2 iv=3D1 prp1=3D... CQHD= BL=3D... Signed-off-by: Mateusz Nowicki Acked-by: Dr. David Alan Gilbert Acked-by: Markus Armbruster --- hmp-commands-info.hx | 15 ++++++++++ hw/nvme/monitor-stub.c | 6 ++++ hw/nvme/monitor.c | 63 ++++++++++++++++++++++++++++++++++++++++++ qapi/machine.json | 17 ++++++++++++ 4 files changed, 101 insertions(+) diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx index b984691c3c..874c1e1970 100644 --- a/hmp-commands-info.hx +++ b/hmp-commands-info.hx @@ -353,6 +353,21 @@ SRST Show emulated NVMe controllers. ERST =20 + { + .name =3D "nvme-queues", + .args_type =3D "", + .params =3D "", + .help =3D "show active NVMe queues and their doorbells", + .cmd_info_hrt =3D qmp_x_query_nvme_queues, + }, + +SRST + ``info nvme-queues`` + Show all active NVMe submission and completion queues, including + head/tail, DMA address of the ring and BAR0-relative doorbell + offset. +ERST + { .name =3D "usbhost", .args_type =3D "", diff --git a/hw/nvme/monitor-stub.c b/hw/nvme/monitor-stub.c index 5eb9f04c8d..489cc4a5c7 100644 --- a/hw/nvme/monitor-stub.c +++ b/hw/nvme/monitor-stub.c @@ -13,3 +13,9 @@ HumanReadableText *qmp_x_query_nvme(Error **errp) error_setg(errp, "NVMe support is not compiled in"); return NULL; } + +HumanReadableText *qmp_x_query_nvme_queues(Error **errp) +{ + error_setg(errp, "NVMe support is not compiled in"); + return NULL; +} diff --git a/hw/nvme/monitor.c b/hw/nvme/monitor.c index 95a6754437..c8161943c0 100644 --- a/hw/nvme/monitor.c +++ b/hw/nvme/monitor.c @@ -74,3 +74,66 @@ HumanReadableText *qmp_x_query_nvme(Error **errp) =20 return human_readable_text_from_str(buf); } + +static void append_sq(GString *buf, NvmeSQueue *sq, unsigned stride) +{ + hwaddr db_off =3D 0x1000 + 2 * sq->sqid * stride; + + g_string_append_printf(buf, + " SQ %u size=3D%-5u head=3D%-5u tail=3D%-5u cqid=3D%-3u " + "prp1=3D0x%016" PRIx64 " SQTDBL=3DBAR0+0x%03" HWADDR_PRIx "\n", + sq->sqid, sq->size, sq->head, sq->tail, sq->cqid, + sq->dma_addr, db_off); +} + +static void append_cq(GString *buf, NvmeCQueue *cq, unsigned stride) +{ + hwaddr db_off =3D 0x1000 + (2 * cq->cqid + 1) * stride; + + g_string_append_printf(buf, + " CQ %u size=3D%-5u head=3D%-5u tail=3D%-5u iv=3D%-5u " + "prp1=3D0x%016" PRIx64 " CQHDBL=3DBAR0+0x%03" HWADDR_PRIx + " phaseTag=3D%u\n", + cq->cqid, cq->size, cq->head, cq->tail, cq->vector, + cq->dma_addr, db_off, cq->phase); +} + +static int collect_queues(Object *obj, void *opaque) +{ + GString *buf =3D opaque; + NvmeCtrl *n; + unsigned stride; + + if (!object_dynamic_cast(obj, TYPE_NVME)) { + return 0; + } + n =3D NVME(obj); + stride =3D 4u << NVME_CAP_DSTRD(ldq_le_p(&n->bar.cap)); + + g_string_append_printf(buf, "%s\n", object_get_canonical_path(obj)); + append_sq(buf, &n->admin_sq, stride); + append_cq(buf, &n->admin_cq, stride); + + for (unsigned i =3D 1; i <=3D n->params.max_ioqpairs; i++) { + if (n->sq && n->sq[i]) { + append_sq(buf, n->sq[i], stride); + } + if (n->cq && n->cq[i]) { + append_cq(buf, n->cq[i], stride); + } + } + return 0; +} + +HumanReadableText *qmp_x_query_nvme_queues(Error **errp) +{ + g_autoptr(GString) buf =3D g_string_new(""); + + object_child_foreach_recursive(object_get_root(), collect_queues, buf); + + if (buf->len =3D=3D 0) { + g_string_append(buf, "no NVMe controllers\n"); + } + + return human_readable_text_from_str(buf); +} diff --git a/qapi/machine.json b/qapi/machine.json index d4a589e768..c21b128e0a 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -1789,6 +1789,23 @@ 'returns': 'HumanReadableText', 'features': [ 'unstable' ] } =20 +## +# @x-query-nvme-queues: +# +# Query state of all active SQ/CQ for emulated NVMe controllers. +# +# Features: +# +# @unstable: This command is meant for debugging. +# +# Returns: per-queue state as human-readable text +# +# Since: 11.1 +## +{ 'command': 'x-query-nvme-queues', + 'returns': 'HumanReadableText', + 'features': [ 'unstable' ] } + ## # @SmbiosEntryPointType: # --=20 2.53.0