]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Add support for NVMe controllers
authorMartin Kletzander <mkletzan@redhat.com>
Mon, 2 Jun 2025 09:37:43 +0000 (11:37 +0200)
committerMartin Kletzander <mkletzan@redhat.com>
Mon, 9 Jun 2025 13:12:42 +0000 (15:12 +0200)
Without any hotplug.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Signed-off-by: Honglei Wang <honglei.wang@smartx.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_command.c
src/qemu/qemu_domain_address.c
src/qemu/qemu_hotplug.c
src/qemu/qemu_validate.c

index f193ba8cca369753c796ade7817a8c1b20544ef0..06e64cf191a3aed24f2293c0236cc913197268f1 100644 (file)
@@ -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++) {
index 9b2faf1e8e375d0ad53c38ce694e5232e36a48e5..bb86cfa0c3f31b6fbbc81754d77f160f6d51dd32 100644 (file)
@@ -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:
index 9427eec643842dcd44c0e6b37038d983cbd45e8f..e1ed8181e303c5caad9803821620d27be7c91701 100644 (file)
@@ -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));
index fee5e1ed87cb351faeb6823b3fa98a4d1a3e1bb6..495b6f3a6a0f736b09cd698ce57fbb7c21c59363 100644 (file)
@@ -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: