6d3351
From 27eff2a6edc81f85757d7d03134dc65d737c316f Mon Sep 17 00:00:00 2001
6d3351
Message-Id: <27eff2a6edc81f85757d7d03134dc65d737c316f@dist-git>
6d3351
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
6d3351
Date: Fri, 9 Jun 2017 12:49:09 +0200
6d3351
Subject: [PATCH] qemu: format virtio-related options on the command line
6d3351
MIME-Version: 1.0
6d3351
Content-Type: text/plain; charset=UTF-8
6d3351
Content-Transfer-Encoding: 8bit
6d3351
6d3351
Format iommu_platform= and ats= for virtio devices.
6d3351
6d3351
https://bugzilla.redhat.com/show_bug.cgi?id=1283251
6d3351
6d3351
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
6d3351
(cherry picked from commit b2cbc3a0607bf26a82911f7db6dcbc09c9bbf5e8)
6d3351
Signed-off-by: Ján Tomko <jtomko@redhat.com>
6d3351
6d3351
Conflicts:
6d3351
	tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
6d3351
          the version again
6d3351
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
6d3351
---
6d3351
 src/qemu/qemu_capabilities.c                       | 12 ++++-
6d3351
 src/qemu/qemu_capabilities.h                       |  2 +
6d3351
 src/qemu/qemu_command.c                            | 58 ++++++++++++++++++++++
6d3351
 tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   |  2 +
6d3351
 .../qemuxml2argv-virtio-options.args               | 37 ++++++++------
6d3351
 tests/qemuxml2argvtest.c                           |  4 +-
6d3351
 6 files changed, 98 insertions(+), 17 deletions(-)
6d3351
6d3351
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
6d3351
index d8f3079083..eea57e4c9c 100644
6d3351
--- a/src/qemu/qemu_capabilities.c
6d3351
+++ b/src/qemu/qemu_capabilities.c
6d3351
@@ -374,6 +374,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
6d3351
               "intel-iommu.eim",
6d3351
 
6d3351
               "intel-iommu.device-iotlb", /* 260 */
6d3351
+              "virtio.iommu_platform",
6d3351
+              "virtio.ats",
6d3351
     );
6d3351
 
6d3351
 
6d3351
@@ -1851,7 +1853,7 @@ struct virQEMUCapsPropTypeObjects {
6d3351
     const char **objects;
6d3351
 };
6d3351
 
6d3351
-static const char *virQEMUCapsVirtioPCIDisableLegacyObjects[] = {
6d3351
+static const char *virQEMUCapsVirtioPCIObjects[] = {
6d3351
      "virtio-balloon-pci",
6d3351
      "virtio-blk-pci",
6d3351
      "virtio-scsi-pci",
6d3351
@@ -1870,7 +1872,13 @@ static const char *virQEMUCapsVirtioPCIDisableLegacyObjects[] = {
6d3351
 static struct virQEMUCapsPropTypeObjects virQEMUCapsPropObjects[] = {
6d3351
     { "disable-legacy",
6d3351
       QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY,
6d3351
-      virQEMUCapsVirtioPCIDisableLegacyObjects }
6d3351
+      virQEMUCapsVirtioPCIObjects },
6d3351
+    { "iommu_platform",
6d3351
+      QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM,
6d3351
+      virQEMUCapsVirtioPCIObjects },
6d3351
+    { "ats",
6d3351
+      QEMU_CAPS_VIRTIO_PCI_ATS,
6d3351
+      virQEMUCapsVirtioPCIObjects },
6d3351
 };
6d3351
 
6d3351
 
6d3351
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
6d3351
index e0f81711fe..bbc6f6812f 100644
6d3351
--- a/src/qemu/qemu_capabilities.h
6d3351
+++ b/src/qemu/qemu_capabilities.h
6d3351
@@ -413,6 +413,8 @@ typedef enum {
6d3351
 
6d3351
     /* 260 */
6d3351
     QEMU_CAPS_INTEL_IOMMU_DEVICE_IOTLB, /* intel-iommu.device-iotlb */
6d3351
+    QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM, /* virtio-*-pci.iommu_platform */
6d3351
+    QEMU_CAPS_VIRTIO_PCI_ATS, /* virtio-*-pci.ats */
6d3351
 
6d3351
     QEMU_CAPS_LAST /* this must always be the last item */
6d3351
 } virQEMUCapsFlags;
6d3351
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
6d3351
index 9c5639b036..e220bf5ba0 100644
6d3351
--- a/src/qemu/qemu_command.c
6d3351
+++ b/src/qemu/qemu_command.c
6d3351
@@ -389,6 +389,38 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
6d3351
 }
6d3351
 
6d3351
 static int
6d3351
+qemuBuildVirtioOptionsStr(virBufferPtr buf,
6d3351
+                          virDomainVirtioOptionsPtr virtio,
6d3351
+                          virQEMUCapsPtr qemuCaps)
6d3351
+{
6d3351
+    if (!virtio)
6d3351
+        return 0;
6d3351
+
6d3351
+    if (virtio->iommu != VIR_TRISTATE_SWITCH_ABSENT) {
6d3351
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM)) {
6d3351
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6d3351
+                           _("the iommu setting is not supported "
6d3351
+                             "with this QEMU binary"));
6d3351
+            return -1;
6d3351
+        }
6d3351
+        virBufferAsprintf(buf, ",iommu_platform=%s",
6d3351
+                          virTristateSwitchTypeToString(virtio->iommu));
6d3351
+    }
6d3351
+    if (virtio->ats != VIR_TRISTATE_SWITCH_ABSENT) {
6d3351
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_ATS)) {
6d3351
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6d3351
+                           _("the ats setting is not supported with this "
6d3351
+                             "QEMU binary"));
6d3351
+            return -1;
6d3351
+        }
6d3351
+        virBufferAsprintf(buf, ",ats=%s",
6d3351
+                          virTristateSwitchTypeToString(virtio->ats));
6d3351
+    }
6d3351
+
6d3351
+    return 0;
6d3351
+}
6d3351
+
6d3351
+static int
6d3351
 qemuBuildRomStr(virBufferPtr buf,
6d3351
                 virDomainDeviceInfoPtr info)
6d3351
 {
6d3351
@@ -2167,6 +2199,10 @@ qemuBuildDriveDevStr(const virDomainDef *def,
6d3351
                               (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN)
6d3351
                               ? "on" : "off");
6d3351
         }
6d3351
+
6d3351
+        if (qemuBuildVirtioOptionsStr(&opt, disk->virtio, qemuCaps) < 0)
6d3351
+            goto error;
6d3351
+
6d3351
         if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
6d3351
             goto error;
6d3351
         break;
6d3351
@@ -2490,6 +2526,8 @@ qemuBuildFSDevStr(const virDomainDef *def,
6d3351
                       QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
6d3351
     virBufferAsprintf(&opt, ",mount_tag=%s", fs->dst);
6d3351
 
6d3351
+    qemuBuildVirtioOptionsStr(&opt, fs->virtio, qemuCaps);
6d3351
+
6d3351
     if (qemuBuildDeviceAddressStr(&opt, def, &fs->info, qemuCaps) < 0)
6d3351
         goto error;
6d3351
 
6d3351
@@ -2734,6 +2772,8 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
6d3351
                                       def->iothread);
6d3351
                 }
6d3351
             }
6d3351
+            if (qemuBuildVirtioOptionsStr(&buf, def->virtio, qemuCaps) < 0)
6d3351
+                goto error;
6d3351
             break;
6d3351
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
6d3351
             virBufferAddLit(&buf, "lsi");
6d3351
@@ -2779,6 +2819,8 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
6d3351
             virBufferAsprintf(&buf, ",vectors=%d",
6d3351
                               def->opts.vioserial.vectors);
6d3351
         }
6d3351
+        if (qemuBuildVirtioOptionsStr(&buf, def->virtio, qemuCaps) < 0)
6d3351
+            goto error;
6d3351
         break;
6d3351
 
6d3351
     case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
6d3351
@@ -3773,12 +3815,16 @@ qemuBuildNicDevStr(virDomainDefPtr def,
6d3351
     virBufferAsprintf(&buf, ",id=%s", net->info.alias);
6d3351
     virBufferAsprintf(&buf, ",mac=%s",
6d3351
                       virMacAddrFormat(&net->mac, macaddr));
6d3351
+
6d3351
     if (qemuBuildDeviceAddressStr(&buf, def, &net->info, qemuCaps) < 0)
6d3351
         goto error;
6d3351
     if (qemuBuildRomStr(&buf, &net->info) < 0)
6d3351
         goto error;
6d3351
     if (bootindex && virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX))
6d3351
         virBufferAsprintf(&buf, ",bootindex=%u", bootindex);
6d3351
+    if (usingVirtio &&
6d3351
+        qemuBuildVirtioOptionsStr(&buf, net->virtio, qemuCaps) < 0)
6d3351
+        goto error;
6d3351
 
6d3351
     if (virBufferCheckError(&buf) < 0)
6d3351
         goto error;
6d3351
@@ -4053,6 +4099,9 @@ qemuBuildMemballoonCommandLine(virCommandPtr cmd,
6d3351
                           virTristateSwitchTypeToString(def->memballoon->autodeflate));
6d3351
     }
6d3351
 
6d3351
+    if (qemuBuildVirtioOptionsStr(&buf, def->memballoon->virtio, qemuCaps) < 0)
6d3351
+        goto error;
6d3351
+
6d3351
     virCommandAddArg(cmd, "-device");
6d3351
     virCommandAddArgBuffer(cmd, &buf;;
6d3351
     return 0;
6d3351
@@ -4183,6 +4232,9 @@ qemuBuildVirtioInputDevStr(const virDomainDef *def,
6d3351
     if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
6d3351
         goto error;
6d3351
 
6d3351
+    if (qemuBuildVirtioOptionsStr(&buf, dev->virtio, qemuCaps) < 0)
6d3351
+        goto error;
6d3351
+
6d3351
     if (virBufferCheckError(&buf) < 0)
6d3351
         goto error;
6d3351
 
6d3351
@@ -4495,6 +4547,9 @@ qemuBuildDeviceVideoStr(const virDomainDef *def,
6d3351
     if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
6d3351
         goto error;
6d3351
 
6d3351
+    if (qemuBuildVirtioOptionsStr(&buf, video->virtio, qemuCaps) < 0)
6d3351
+        goto error;
6d3351
+
6d3351
     if (virBufferCheckError(&buf) < 0)
6d3351
         goto error;
6d3351
 
6d3351
@@ -5860,6 +5915,9 @@ qemuBuildRNGDevStr(const virDomainDef *def,
6d3351
             virBufferAddLit(&buf, ",period=1000");
6d3351
     }
6d3351
 
6d3351
+    if (qemuBuildVirtioOptionsStr(&buf, dev->virtio, qemuCaps) < 0)
6d3351
+        goto error;
6d3351
+
6d3351
     if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
6d3351
         goto error;
6d3351
     if (virBufferCheckError(&buf) < 0)
6d3351
diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
6d3351
index 29a483d123..2140eab398 100644
6d3351
--- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
6d3351
+++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml
6d3351
@@ -215,6 +215,8 @@
6d3351
   <flag name='intel-iommu.caching-mode'/>
6d3351
   <flag name='intel-iommu.eim'/>
6d3351
   <flag name='intel-iommu.device-iotlb'/>
6d3351
+  <flag name='virtio.iommu_platform'/>
6d3351
+  <flag name='virtio.ats'/>
6d3351
   <version>2008090</version>
6d3351
   <kvmVersion>0</kvmVersion>
6d3351
   <package> (v2.9.0-rc0-142-g940a8ce)</package>
6d3351
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.args
6d3351
index f9f3c2cbad..ce0388dfc2 100644
6d3351
--- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.args
6d3351
+++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-options.args
6d3351
@@ -16,26 +16,35 @@ QEMU_AUDIO_DRV=none \
6d3351
 -monitor unix:/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server,nowait \
6d3351
 -no-acpi \
6d3351
 -boot c \
6d3351
--device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x8 \
6d3351
--device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x9 \
6d3351
+-device virtio-scsi-pci,iommu_platform=on,ats=on,id=scsi0,bus=pci.0,addr=0x8 \
6d3351
+-device virtio-serial-pci,id=virtio-serial0,iommu_platform=on,ats=on,bus=pci.0,\
6d3351
+addr=0x9 \
6d3351
 -usb \
6d3351
 -drive file=/var/lib/libvirt/images/img1,format=raw,if=none,\
6d3351
 id=drive-virtio-disk0 \
6d3351
--device virtio-blk-pci,bus=pci.0,addr=0xa,drive=drive-virtio-disk0,\
6d3351
-id=virtio-disk0 \
6d3351
+-device virtio-blk-pci,iommu_platform=on,ats=on,bus=pci.0,addr=0xa,\
6d3351
+drive=drive-virtio-disk0,id=virtio-disk0 \
6d3351
 -fsdev local,security_model=passthrough,id=fsdev-fs0,path=/export/fs1 \
6d3351
--device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=fs1,bus=pci.0,addr=0x3 \
6d3351
+-device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=fs1,iommu_platform=on,\
6d3351
+ats=on,bus=pci.0,addr=0x3 \
6d3351
 -fsdev local,security_model=mapped,writeout=immediate,id=fsdev-fs1,\
6d3351
 path=/export/fs2 \
6d3351
--device virtio-9p-pci,id=fs1,fsdev=fsdev-fs1,mount_tag=fs2,bus=pci.0,addr=0x4 \
6d3351
--device virtio-net-pci,vlan=0,id=net0,mac=52:54:56:58:5a:5c,bus=pci.0,addr=0x6 \
6d3351
+-device virtio-9p-pci,id=fs1,fsdev=fsdev-fs1,mount_tag=fs2,iommu_platform=on,\
6d3351
+ats=on,bus=pci.0,addr=0x4 \
6d3351
+-device virtio-net-pci,vlan=0,id=net0,mac=52:54:56:58:5a:5c,bus=pci.0,addr=0x6,\
6d3351
+iommu_platform=on,ats=on \
6d3351
 -net user,vlan=0,name=hostnet0 \
6d3351
--device virtio-mouse-pci,id=input0,bus=pci.0,addr=0xe \
6d3351
--device virtio-keyboard-pci,id=input1,bus=pci.0,addr=0x10 \
6d3351
--device virtio-tablet-pci,id=input2,bus=pci.0,addr=0x11 \
6d3351
+-device virtio-mouse-pci,id=input0,bus=pci.0,addr=0xe,iommu_platform=on,ats=on \
6d3351
+-device virtio-keyboard-pci,id=input1,bus=pci.0,addr=0x10,iommu_platform=on,\
6d3351
+ats=on \
6d3351
+-device virtio-tablet-pci,id=input2,bus=pci.0,addr=0x11,iommu_platform=on,\
6d3351
+ats=on \
6d3351
 -device virtio-input-host-pci,id=input3,evdev=/dev/input/event1234,bus=pci.0,\
6d3351
-addr=0x12 \
6d3351
--device virtio-gpu-pci,id=video0,virgl=on,bus=pci.0,addr=0x2 \
6d3351
--device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0xc \
6d3351
+addr=0x12,iommu_platform=on,ats=on \
6d3351
+-device virtio-gpu-pci,id=video0,virgl=on,bus=pci.0,addr=0x2,iommu_platform=on,\
6d3351
+ats=on \
6d3351
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0xc,iommu_platform=on,\
6d3351
+ats=on \
6d3351
 -object rng-random,id=objrng0,filename=/dev/random \
6d3351
--device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0xd
6d3351
+-device virtio-rng-pci,rng=objrng0,id=rng0,iommu_platform=on,ats=on,bus=pci.0,\
6d3351
+addr=0xd
6d3351
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
6d3351
index c186780ef1..175037bf96 100644
6d3351
--- a/tests/qemuxml2argvtest.c
6d3351
+++ b/tests/qemuxml2argvtest.c
6d3351
@@ -2558,7 +2558,9 @@ mymain(void)
6d3351
             QEMU_CAPS_VIRTIO_GPU_VIRGL,
6d3351
             QEMU_CAPS_DEVICE_VIRTIO_RNG,
6d3351
             QEMU_CAPS_OBJECT_RNG_RANDOM,
6d3351
-            QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
6d3351
+            QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
6d3351
+            QEMU_CAPS_VIRTIO_PCI_IOMMU_PLATFORM,
6d3351
+            QEMU_CAPS_VIRTIO_PCI_ATS);
6d3351
 
6d3351
     DO_TEST("fd-memory-numa-topology", QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_FILE,
6d3351
             QEMU_CAPS_KVM);
6d3351
-- 
6d3351
2.13.1
6d3351