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>
---
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 109c01a70d..98a4401043 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 4067443309..b392e053ab 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]>, \
@@ -8614,6 +8615,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;
@@ -9109,7 +9117,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);
@@ -9389,6 +9398,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 ebf1fcfdcd..5ef3ebee29 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