From: Martin Kletzander Date: Mon, 2 Jun 2025 09:37:43 +0000 (+0200) Subject: qemu: Add support for NVMe controllers X-Git-Tag: v11.5.0-rc1~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1402c407141f514c6ecef7deef7e0d337cb82df5;p=thirdparty%2Flibvirt.git qemu: Add support for NVMe controllers Without any hotplug. Signed-off-by: Martin Kletzander Signed-off-by: Honglei Wang Reviewed-by: Ján Tomko --- diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f193ba8cca..06e64cf191 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2854,6 +2854,17 @@ qemuBuildControllerDevProps(const virDomainDef *domainDef, break; case VIR_DOMAIN_CONTROLLER_TYPE_NVME: + if (virJSONValueObjectAdd(&props, + "s:driver", "nvme", + "s:id", def->info.alias, + "s:serial", def->opts.nvmeopts.serial, + "p:num_queues", def->queues, + "T:ioeventfd", def->ioeventfd, + NULL) < 0) + return -1; + + break; + case VIR_DOMAIN_CONTROLLER_TYPE_IDE: case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: @@ -3016,6 +3027,7 @@ qemuBuildControllersCommandLine(virCommand *cmd, VIR_DOMAIN_CONTROLLER_TYPE_IDE, VIR_DOMAIN_CONTROLLER_TYPE_SATA, VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL, + VIR_DOMAIN_CONTROLLER_TYPE_NVME, }; for (i = 0; i < G_N_ELEMENTS(contOrder); i++) { diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 9b2faf1e8e..bb86cfa0c3 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -617,6 +617,8 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, break; case VIR_DOMAIN_CONTROLLER_TYPE_NVME: + return pciFlags; + case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_CCID: case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 9427eec643..e1ed8181e3 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -5941,7 +5941,8 @@ qemuDomainDetachPrepController(virDomainObj *vm, int idx; virDomainControllerDef *controller = NULL; - if (match->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { + if (match->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI && + match->type != VIR_DOMAIN_CONTROLLER_TYPE_NVME) { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("'%1$s' controller cannot be hot unplugged."), virDomainControllerTypeToString(match->type)); diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index fee5e1ed87..495b6f3a6a 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3633,6 +3633,26 @@ qemuValidateDomainDeviceDefControllerSATA(const virDomainControllerDef *controll } +static int +qemuValidateDomainDeviceDefControllerNVME(const virDomainControllerDef *controller, + const virDomainDef *def G_GNUC_UNUSED, + virQEMUCaps *qemuCaps) +{ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVME)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("NVMe controllers are not supported with this QEMU binary")); + } + + if (!controller->opts.nvmeopts.serial) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing mandatory serial for NVMe controller")); + return -1; + } + + return 0; +} + + static int qemuValidateDomainDeviceDefControllerIDE(const virDomainControllerDef *controller, const virDomainDef *def) @@ -3804,10 +3824,17 @@ qemuValidateDomainDeviceDefControllerAttributes(const virDomainControllerDef *co (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI || controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_TRANSITIONAL || controller->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_NON_TRANSITIONAL))) { - if (controller->queues) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("'queues' is only supported by virtio-scsi controller")); - return -1; + if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_NVME) { + if (controller->queues) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("'queues' is only supported by virtio-scsi and nvme controllers")); + return -1; + } + if (controller->ioeventfd) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("'ioeventfd' is only supported by virtio-scsi and nvme controllers")); + return -1; + } } if (controller->cmd_per_lun) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -3819,11 +3846,6 @@ qemuValidateDomainDeviceDefControllerAttributes(const virDomainControllerDef *co _("'max_sectors' is only supported by virtio-scsi controller")); return -1; } - if (controller->ioeventfd) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("'ioeventfd' is only supported by virtio-scsi controller")); - return -1; - } if (controller->iothread) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("'iothread' is only supported for virtio-scsi controller")); @@ -4408,6 +4430,10 @@ qemuValidateDomainDeviceDefController(const virDomainControllerDef *controller, break; case VIR_DOMAIN_CONTROLLER_TYPE_NVME: + ret = qemuValidateDomainDeviceDefControllerNVME(controller, def, + qemuCaps); + break; + case VIR_DOMAIN_CONTROLLER_TYPE_FDC: case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: case VIR_DOMAIN_CONTROLLER_TYPE_CCID: