* [PULL 1/5] include/block: define constants for NVME string fields
2026-05-18 12:07 [PULL 0/5] hw/nvme queue Klaus Jensen
@ 2026-05-18 12:07 ` Klaus Jensen
2026-05-18 12:07 ` [PULL 2/5] hw/nvme: report error for oversized 'serial' parameter Klaus Jensen
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Klaus Jensen @ 2026-05-18 12:07 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Daniel P. Berrangé, Klaus Jensen, Keith Busch,
Klaus Jensen, Jesper Devantier, Stefan Hajnoczi, Fam Zheng,
Kevin Wolf, Hanna Reitz, qemu-block
From: Daniel P. Berrangé <berrange@redhat.com>
The version, model and serial fields accept fixed length strings.
Add constants to enable user supplied strings to be validated.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
---
include/block/nvme.h | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/include/block/nvme.h b/include/block/nvme.h
index 9d7159ed7a7a..e4e7be51205e 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -1134,12 +1134,16 @@ enum NvmeIdCns {
NVME_ID_CNS_CS_IND_NS_ALLOCATED = 0x1f,
};
+#define NVME_ID_CTRL_SN_MAX_LEN 20
+#define NVME_ID_CTRL_MN_MAX_LEN 40
+#define NVME_ID_CTRL_FR_MAX_LEN 8
+
typedef struct QEMU_PACKED NvmeIdCtrl {
uint16_t vid;
uint16_t ssvid;
- uint8_t sn[20];
- uint8_t mn[40];
- uint8_t fr[8];
+ uint8_t sn[NVME_ID_CTRL_SN_MAX_LEN];
+ uint8_t mn[NVME_ID_CTRL_MN_MAX_LEN];
+ uint8_t fr[NVME_ID_CTRL_FR_MAX_LEN];
uint8_t rab;
uint8_t ieee[3];
uint8_t cmic;
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PULL 2/5] hw/nvme: report error for oversized 'serial' parameter
2026-05-18 12:07 [PULL 0/5] hw/nvme queue Klaus Jensen
2026-05-18 12:07 ` [PULL 1/5] include/block: define constants for NVME string fields Klaus Jensen
@ 2026-05-18 12:07 ` Klaus Jensen
2026-05-18 12:07 ` [PULL 3/5] hw/nvme: add user controlled 'model' property Klaus Jensen
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Klaus Jensen @ 2026-05-18 12:07 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Daniel P. Berrangé, Klaus Jensen, Keith Busch,
Klaus Jensen, Jesper Devantier, qemu-block
From: Daniel P. Berrangé <berrange@redhat.com>
The 'serial' accepted by the NVME device is at most 20 characters
long. An over-sized user supplied value should be reported rather
than silently truncated.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
---
hw/nvme/ctrl.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index be6c7028cb58..2556aced2a47 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -8602,6 +8602,11 @@ static bool nvme_check_params(NvmeCtrl *n, Error **errp)
error_setg(errp, "serial property not set");
return false;
}
+ if (strlen(params->serial) > NVME_ID_CTRL_SN_MAX_LEN) {
+ error_setg(errp, "'serial' parameter '%s' can be at most '%d' characters",
+ params->serial, NVME_ID_CTRL_SN_MAX_LEN);
+ return false;
+ }
if (params->mqes < 1) {
error_setg(errp, "mqes property cannot be less than 1");
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PULL 3/5] hw/nvme: add user controlled 'model' property
2026-05-18 12:07 [PULL 0/5] hw/nvme queue Klaus Jensen
2026-05-18 12:07 ` [PULL 1/5] include/block: define constants for NVME string fields Klaus Jensen
2026-05-18 12:07 ` [PULL 2/5] hw/nvme: report error for oversized 'serial' parameter Klaus Jensen
@ 2026-05-18 12:07 ` Klaus Jensen
2026-05-18 12:07 ` [PULL 4/5] hw/nvme: add user controlled 'firmware-version' property Klaus Jensen
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Klaus Jensen @ 2026-05-18 12:07 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Daniel P. Berrangé, Klaus Jensen, Keith Busch,
Klaus Jensen, Jesper Devantier, Pierrick Bouvier, qemu-block
From: Daniel P. Berrangé <berrange@redhat.com>
This enables overriding the built in default "QEMU NVMe Ctrl" string
with a user specified string. The value can be at most 40 characters
in length.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
---
docs/system/devices/nvme.rst | 5 +++++
hw/nvme/ctrl.c | 14 ++++++++++++--
hw/nvme/nvme.h | 1 +
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/docs/system/devices/nvme.rst b/docs/system/devices/nvme.rst
index 6509b35fcb4e..109c01a70d50 100644
--- a/docs/system/devices/nvme.rst
+++ b/docs/system/devices/nvme.rst
@@ -60,6 +60,11 @@ parameters.
the SMART / Health information extended log become available in the
controller. We emulate version 5 of this log page.
+``model`` (default: ``QEMU NVMe Ctrl``)
+ Override the default reported model, which can be used when needing
+ to more closely impersonate a particular device type. The model name
+ can be a maximum of 40 characters in length.
+
Additional Namespaces
---------------------
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 2556aced2a47..4822bc0a99b1 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -43,7 +43,8 @@
* atomic.dn=<on|off[optional]>, \
* atomic.awun<N[optional]>, \
* atomic.awupf<N[optional]>, \
- * subsys=<subsys_id>
+ * subsys=<subsys_id>, \
+ * model=<model-str>
* -device nvme-ns,drive=<drive_id>,bus=<bus_name>,nsid=<nsid>,\
* zoned=<true|false[optional]>, \
* subsys=<subsys_id>,shared=<true|false[optional]>, \
@@ -8608,6 +8609,13 @@ static bool nvme_check_params(NvmeCtrl *n, Error **errp)
return false;
}
+ if (params->model &&
+ strlen(params->model) > NVME_ID_CTRL_MN_MAX_LEN) {
+ error_setg(errp, "'model' parameter '%s' can be at most '%d' characters",
+ params->model, NVME_ID_CTRL_MN_MAX_LEN);
+ return false;
+ }
+
if (params->mqes < 1) {
error_setg(errp, "mqes property cannot be less than 1");
return false;
@@ -9101,7 +9109,8 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
id->vid = cpu_to_le16(pci_get_word(pci_conf + PCI_VENDOR_ID));
id->ssvid = cpu_to_le16(pci_get_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID));
- strpadcpy((char *)id->mn, sizeof(id->mn), "QEMU NVMe Ctrl", ' ');
+ strpadcpy((char *)id->mn, sizeof(id->mn),
+ n->params.model ? n->params.model : "QEMU NVMe Ctrl", ' ');
strpadcpy((char *)id->fr, sizeof(id->fr), QEMU_VERSION, ' ');
strpadcpy((char *)id->sn, sizeof(id->sn), n->params.serial, ' ');
@@ -9381,6 +9390,7 @@ static const Property nvme_props[] = {
DEFINE_PROP_LINK("subsys", NvmeCtrl, subsys, TYPE_NVME_SUBSYS,
NvmeSubsystem *),
DEFINE_PROP_STRING("serial", NvmeCtrl, params.serial),
+ DEFINE_PROP_STRING("model", NvmeCtrl, params.model),
DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, params.cmb_size_mb, 0),
DEFINE_PROP_UINT32("num_queues", NvmeCtrl, params.num_queues, 0),
DEFINE_PROP_UINT32("max_ioqpairs", NvmeCtrl, params.max_ioqpairs, 64),
diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h
index d66f7dc82d5c..ebf1fcfdcde0 100644
--- a/hw/nvme/nvme.h
+++ b/hw/nvme/nvme.h
@@ -542,6 +542,7 @@ typedef struct NvmeCQueue {
typedef struct NvmeParams {
char *serial;
+ char *model;
uint32_t num_queues; /* deprecated since 5.1 */
uint32_t max_ioqpairs;
uint16_t msix_qsize;
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PULL 4/5] hw/nvme: add user controlled 'firmware-version' property
2026-05-18 12:07 [PULL 0/5] hw/nvme queue Klaus Jensen
` (2 preceding siblings ...)
2026-05-18 12:07 ` [PULL 3/5] hw/nvme: add user controlled 'model' property Klaus Jensen
@ 2026-05-18 12:07 ` Klaus Jensen
2026-05-18 12:07 ` [PULL 5/5] hw/nvme: fix admin cq msix setup Klaus Jensen
2026-05-19 12:39 ` [PULL 0/5] hw/nvme queue Stefan Hajnoczi
5 siblings, 0 replies; 7+ messages in thread
From: Klaus Jensen @ 2026-05-18 12:07 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Daniel P. Berrangé, Klaus Jensen, Keith Busch,
Klaus Jensen, Jesper Devantier, Pierrick Bouvier, qemu-block
From: Daniel P. Berrangé <berrange@redhat.com>
This enables overriding the built in default QEMU project version string
with a user specified string. The value can be at most 8 characters
in length.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
---
docs/system/devices/nvme.rst | 5 +++++
hw/nvme/ctrl.c | 14 ++++++++++++--
hw/nvme/nvme.h | 1 +
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/docs/system/devices/nvme.rst b/docs/system/devices/nvme.rst
index 109c01a70d50..98a44010438b 100644
--- a/docs/system/devices/nvme.rst
+++ b/docs/system/devices/nvme.rst
@@ -65,6 +65,11 @@ parameters.
to more closely impersonate a particular device type. The model name
can be a maximum of 40 characters in length.
+``firmware-version`` (default: current QEMU version number)
+ Override the default reported firmware version, which can be used when
+ needing to more closely impersonate a particular device type. The version
+ can be a maximum of 8 characters in length.
+
Additional Namespaces
---------------------
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 4822bc0a99b1..5b03929451d0 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -44,7 +44,8 @@
* atomic.awun<N[optional]>, \
* atomic.awupf<N[optional]>, \
* subsys=<subsys_id>, \
- * model=<model-str>
+ * model=<model-str>, \
+ * firmware-version=<version-str>
* -device nvme-ns,drive=<drive_id>,bus=<bus_name>,nsid=<nsid>,\
* zoned=<true|false[optional]>, \
* subsys=<subsys_id>,shared=<true|false[optional]>, \
@@ -8616,6 +8617,13 @@ static bool nvme_check_params(NvmeCtrl *n, Error **errp)
return false;
}
+ if (params->firmware_version &&
+ strlen(params->firmware_version) > NVME_ID_CTRL_FR_MAX_LEN) {
+ error_setg(errp, "'firmware-version' parameter '%s' can be at most '%d' characters",
+ params->firmware_version, NVME_ID_CTRL_FR_MAX_LEN);
+ return false;
+ }
+
if (params->mqes < 1) {
error_setg(errp, "mqes property cannot be less than 1");
return false;
@@ -9111,7 +9119,8 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
id->ssvid = cpu_to_le16(pci_get_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID));
strpadcpy((char *)id->mn, sizeof(id->mn),
n->params.model ? n->params.model : "QEMU NVMe Ctrl", ' ');
- strpadcpy((char *)id->fr, sizeof(id->fr), QEMU_VERSION, ' ');
+ strpadcpy((char *)id->fr, sizeof(id->fr),
+ n->params.firmware_version ? n->params.firmware_version : QEMU_VERSION, ' ');
strpadcpy((char *)id->sn, sizeof(id->sn), n->params.serial, ' ');
id->cntlid = cpu_to_le16(n->cntlid);
@@ -9391,6 +9400,7 @@ static const Property nvme_props[] = {
NvmeSubsystem *),
DEFINE_PROP_STRING("serial", NvmeCtrl, params.serial),
DEFINE_PROP_STRING("model", NvmeCtrl, params.model),
+ DEFINE_PROP_STRING("firmware-version", NvmeCtrl, params.firmware_version),
DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, params.cmb_size_mb, 0),
DEFINE_PROP_UINT32("num_queues", NvmeCtrl, params.num_queues, 0),
DEFINE_PROP_UINT32("max_ioqpairs", NvmeCtrl, params.max_ioqpairs, 64),
diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h
index ebf1fcfdcde0..5ef3ebee29e5 100644
--- a/hw/nvme/nvme.h
+++ b/hw/nvme/nvme.h
@@ -543,6 +543,7 @@ typedef struct NvmeCQueue {
typedef struct NvmeParams {
char *serial;
char *model;
+ char *firmware_version;
uint32_t num_queues; /* deprecated since 5.1 */
uint32_t max_ioqpairs;
uint16_t msix_qsize;
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PULL 5/5] hw/nvme: fix admin cq msix setup
2026-05-18 12:07 [PULL 0/5] hw/nvme queue Klaus Jensen
` (3 preceding siblings ...)
2026-05-18 12:07 ` [PULL 4/5] hw/nvme: add user controlled 'firmware-version' property Klaus Jensen
@ 2026-05-18 12:07 ` Klaus Jensen
2026-05-19 12:39 ` [PULL 0/5] hw/nvme queue Stefan Hajnoczi
5 siblings, 0 replies; 7+ messages in thread
From: Klaus Jensen @ 2026-05-18 12:07 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Klaus Jensen, qemu-stable, Andreas Hindborg,
Keith Busch, Klaus Jensen, Jesper Devantier, qemu-block
From: Klaus Jensen <k.jensen@samsung.com>
If MSI-X is not enabled when the admin completion queue is created,
msix_vector_use() is not called. But, if MSI-X is subsequently enabled,
msix_notify() will fail to fire the interrupt because the use count for
the vector remains at 0.
msix_vector_use/unuse should be called if MSI-X is *present*, not
*enabled*. Fix this.
Cc: qemu-stable@nongnu.org
Reported-by: Andreas Hindborg <a.hindborg@samsung.com>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
---
hw/nvme/ctrl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 5b03929451d0..815f39173c8a 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -5519,7 +5519,7 @@ static void nvme_free_cq(NvmeCQueue *cq, NvmeCtrl *n)
event_notifier_set_handler(&cq->notifier, NULL);
event_notifier_cleanup(&cq->notifier);
}
- if (msix_enabled(pci) && cq->irq_enabled) {
+ if (msix_present(pci) && cq->irq_enabled) {
msix_vector_unuse(pci, cq->vector);
}
if (cq->cqid) {
@@ -5560,7 +5560,7 @@ static void nvme_init_cq(NvmeCQueue *cq, NvmeCtrl *n, uint64_t dma_addr,
{
PCIDevice *pci = PCI_DEVICE(n);
- if (msix_enabled(pci) && irq_enabled) {
+ if (msix_present(pci) && irq_enabled) {
msix_vector_use(pci, vector);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PULL 0/5] hw/nvme queue
2026-05-18 12:07 [PULL 0/5] hw/nvme queue Klaus Jensen
` (4 preceding siblings ...)
2026-05-18 12:07 ` [PULL 5/5] hw/nvme: fix admin cq msix setup Klaus Jensen
@ 2026-05-19 12:39 ` Stefan Hajnoczi
5 siblings, 0 replies; 7+ messages in thread
From: Stefan Hajnoczi @ 2026-05-19 12:39 UTC (permalink / raw)
To: Klaus Jensen; +Cc: qemu-devel, Peter Maydell, Klaus Jensen
[-- Attachment #1: Type: text/plain, Size: 116 bytes --]
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/11.1 for any user-visible changes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread