adeaf8
From cddd76962c2a0fcbb8c80240d234b7d0d657324d Mon Sep 17 00:00:00 2001
2daa92
From: Cole Robinson <crobinso@redhat.com>
Daniel P. Berrange 11755d
Date: Fri, 30 Aug 2013 12:41:36 -0400
adeaf8
Subject: [PATCH] qemu: Support virtio-mmio transport for virtio on ARM
2daa92
2daa92
Starting with qemu 1.6, the qemu-system-arm vexpress-a9 model has a
2daa92
hardcoded virtio-mmio transport which enables attaching all virtio
2daa92
devices.
2daa92
2daa92
On the command line, we have to use virtio-XXX-device rather than
2daa92
virtio-XXX-pci, thankfully s390 already set the precedent here so
2daa92
it's fairly straight forward.
2daa92
2daa92
At the XML level, this adds a new device address type virtio-mmio.
2daa92
The controller and addressing don't have any subelements at the
2daa92
moment because we they aren't needed for this usecase, but could
2daa92
be added later if needed.
2daa92
2daa92
Add a test case for an ARM guest with one of every virtio device
2daa92
enabled.
2daa92
---
2daa92
 src/conf/domain_conf.c                             | 12 +++-
2daa92
 src/conf/domain_conf.h                             |  1 +
Daniel P. Berrange 11755d
 src/qemu/qemu_capabilities.c                       | 17 ++++--
Daniel P. Berrange 11755d
 src/qemu/qemu_capabilities.h                       |  2 +
2daa92
 src/qemu/qemu_command.c                            | 65 +++++++++++++++++-----
2daa92
 .../qemuxml2argv-arm-vexpressa9-virtio.args        | 14 +++++
2daa92
 .../qemuxml2argv-arm-vexpressa9-virtio.xml         | 45 +++++++++++++++
2daa92
 tests/qemuxml2argvtest.c                           |  4 ++
Daniel P. Berrange 11755d
 8 files changed, 139 insertions(+), 21 deletions(-)
2daa92
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args
2daa92
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.xml
2daa92
2daa92
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
Daniel P. Berrange 11755d
index 2c62a2d..3b51ae8 100644
2daa92
--- a/src/conf/domain_conf.c
2daa92
+++ b/src/conf/domain_conf.c
2daa92
@@ -210,7 +210,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
2daa92
               "usb",
2daa92
               "spapr-vio",
2daa92
               "virtio-s390",
2daa92
-              "ccw")
2daa92
+              "ccw",
2daa92
+              "virtio-mmio")
2daa92
 
2daa92
 VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
2daa92
               "block",
Daniel P. Berrange 11755d
@@ -2390,6 +2391,7 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info,
2daa92
         return 1;
2daa92
 
2daa92
     case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390:
2daa92
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
2daa92
         return 1;
2daa92
 
2daa92
     case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW:
Daniel P. Berrange 11755d
@@ -3031,6 +3033,9 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
2daa92
                           info->addr.ccw.devno);
2daa92
         break;
2daa92
 
2daa92
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
2daa92
+        break;
2daa92
+
2daa92
     default:
2daa92
         virReportError(VIR_ERR_INTERNAL_ERROR,
2daa92
                        _("unknown address type '%d'"), info->type);
Daniel P. Berrange 11755d
@@ -3495,6 +3500,9 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
2daa92
             goto cleanup;
2daa92
         break;
2daa92
 
2daa92
+    case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
2daa92
+        break;
2daa92
+
2daa92
     default:
2daa92
         /* Should not happen */
2daa92
         virReportError(VIR_ERR_INTERNAL_ERROR,
Daniel P. Berrange 11755d
@@ -5827,6 +5835,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
2daa92
         def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO &&
2daa92
         def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
2daa92
         def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 &&
2daa92
+        def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO &&
2daa92
         def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2daa92
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2daa92
                        _("Controllers must use the 'pci' address type"));
Daniel P. Berrange 11755d
@@ -6387,6 +6396,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
2daa92
         def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO &&
2daa92
         def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
2daa92
         def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 &&
2daa92
+        def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO &&
2daa92
         def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2daa92
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2daa92
                        _("Network interfaces must use 'pci' address type"));
2daa92
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
Daniel P. Berrange 11755d
index 380e2bb..1d70eba 100644
2daa92
--- a/src/conf/domain_conf.h
2daa92
+++ b/src/conf/domain_conf.h
2daa92
@@ -207,6 +207,7 @@ enum virDomainDeviceAddressType {
2daa92
     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO,
2daa92
     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390,
2daa92
     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW,
2daa92
+    VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO,
2daa92
 
2daa92
     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
2daa92
 };
2daa92
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
Daniel P. Berrange 11755d
index 72df793..a0f7773 100644
2daa92
--- a/src/qemu/qemu_capabilities.c
2daa92
+++ b/src/qemu/qemu_capabilities.c
Daniel P. Berrange 11755d
@@ -237,6 +237,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
Daniel P. Berrange 11755d
               "dmi-to-pci-bridge",
Daniel P. Berrange 11755d
               "i440fx-pci-hole64-size",
Daniel P. Berrange 11755d
               "q35-pci-hole64-size",
Daniel P. Berrange 11755d
+
Daniel P. Berrange 11755d
+              "virtio-mmio", /* 155 */
2daa92
     );
2daa92
 
2daa92
 struct _virQEMUCaps {
Daniel P. Berrange 11755d
@@ -1385,6 +1387,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
2daa92
     { "vfio-pci", QEMU_CAPS_DEVICE_VFIO_PCI },
2daa92
     { "scsi-generic", QEMU_CAPS_DEVICE_SCSI_GENERIC },
Daniel P. Berrange 11755d
     { "i82801b11-bridge", QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE },
2daa92
+    { "virtio-mmio", QEMU_CAPS_DEVICE_VIRTIO_MMIO },
2daa92
 };
2daa92
 
2daa92
 static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = {
Daniel P. Berrange 11755d
@@ -2831,17 +2834,19 @@ virQEMUCapsUsedQMP(virQEMUCapsPtr qemuCaps)
2daa92
 bool
2daa92
 virQEMUCapsSupportsChardev(virDomainDefPtr def,
2daa92
                            virQEMUCapsPtr qemuCaps,
2daa92
-                           virDomainChrDefPtr chr ATTRIBUTE_UNUSED)
2daa92
+                           virDomainChrDefPtr chr)
2daa92
 {
2daa92
     if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
2daa92
         !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
2daa92
         return false;
2daa92
 
2daa92
-    /* This may not be true for all ARM machine types, but at least
2daa92
-     * the only supported serial devices of vexpress and versatile
2daa92
-     * don't have the -chardev property wired up. */
2daa92
     if (def->os.arch != VIR_ARCH_ARMV7L)
2daa92
-        return false;
2daa92
+        return true;
2daa92
 
2daa92
-    return true;
2daa92
+    /* This may not be true for all ARM machine types, but at least
2daa92
+     * the only supported non-virtio serial devices of vexpress and versatile
2daa92
+     * don't have the -chardev property wired up. */
2daa92
+    return (chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO ||
2daa92
+            (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
2daa92
+             chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO));
2daa92
 }
2daa92
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
Daniel P. Berrange 11755d
index 5180ee9..e000ce5 100644
2daa92
--- a/src/qemu/qemu_capabilities.h
2daa92
+++ b/src/qemu/qemu_capabilities.h
Daniel P. Berrange 11755d
@@ -194,6 +194,8 @@ enum virQEMUCapsFlags {
Daniel P. Berrange 11755d
     QEMU_CAPS_I440FX_PCI_HOLE64_SIZE = 153, /* i440FX-pcihost.pci-hole64-size */
Daniel P. Berrange 11755d
     QEMU_CAPS_Q35_PCI_HOLE64_SIZE = 154, /* q35-pcihost.pci-hole64-size */
2daa92
 
Daniel P. Berrange 11755d
+    QEMU_CAPS_DEVICE_VIRTIO_MMIO = 155, /* -device virtio-mmio */
Daniel P. Berrange 11755d
+
2daa92
     QEMU_CAPS_LAST,                   /* this must always be the last item */
2daa92
 };
Daniel P. Berrange 11755d
 
2daa92
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
Daniel P. Berrange 11755d
index 787381b..efbfc97 100644
2daa92
--- a/src/qemu/qemu_command.c
2daa92
+++ b/src/qemu/qemu_command.c
2daa92
@@ -418,22 +418,27 @@ cleanup:
2daa92
 }
2daa92
 
2daa92
 static bool
2daa92
-qemuDomainSupportsNicdev(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
2daa92
+qemuDomainSupportsNicdev(virDomainDefPtr def,
2daa92
+                         virQEMUCapsPtr qemuCaps,
2daa92
+                         virDomainNetDefPtr net)
2daa92
 {
2daa92
     if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
2daa92
         return false;
2daa92
 
2daa92
-    /* arm boards require legacy -net nic */
2daa92
-    if (def->os.arch == VIR_ARCH_ARMV7L)
2daa92
+    /* non-virtio ARM nics require legacy -net nic */
2daa92
+    if (def->os.arch == VIR_ARCH_ARMV7L &&
2daa92
+        net->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
2daa92
         return false;
2daa92
 
2daa92
     return true;
2daa92
 }
2daa92
 
2daa92
 static bool
2daa92
-qemuDomainSupportsNetdev(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
2daa92
+qemuDomainSupportsNetdev(virDomainDefPtr def,
2daa92
+                         virQEMUCapsPtr qemuCaps,
2daa92
+                         virDomainNetDefPtr net)
2daa92
 {
2daa92
-    if (!qemuDomainSupportsNicdev(def, qemuCaps))
2daa92
+    if (!qemuDomainSupportsNicdev(def, qemuCaps, net))
2daa92
         return false;
2daa92
     return virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV);
2daa92
 }
2daa92
@@ -474,7 +479,7 @@ qemuOpenVhostNet(virDomainDefPtr def,
2daa92
      * option), don't try to open the device.
2daa92
      */
2daa92
     if (!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOST_NET) &&
2daa92
-          qemuDomainSupportsNetdev(def, qemuCaps))) {
2daa92
+          qemuDomainSupportsNetdev(def, qemuCaps, net))) {
2daa92
         if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) {
2daa92
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2daa92
                            "%s", _("vhost-net is not supported with "
Daniel P. Berrange 11755d
@@ -1154,8 +1159,8 @@ cleanup:
2daa92
 }
2daa92
 
2daa92
 static void
2daa92
-qemuDomainPrimeS390VirtioDevices(virDomainDefPtr def,
2daa92
-                                 enum virDomainDeviceAddressType type)
2daa92
+qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
2daa92
+                                     enum virDomainDeviceAddressType type)
2daa92
 {
2daa92
     /*
2daa92
        declare address-less virtio devices to be of address type 'type'
Daniel P. Berrange 11755d
@@ -1289,7 +1294,7 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def,
2daa92
 
2daa92
     if (STREQLEN(def->os.machine, "s390-ccw", 8) &&
2daa92
         virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
2daa92
-        qemuDomainPrimeS390VirtioDevices(
2daa92
+        qemuDomainPrimeVirtioDeviceAddresses(
2daa92
             def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW);
2daa92
 
2daa92
         if (!(addrs = qemuDomainCCWAddressSetCreate()))
Daniel P. Berrange 11755d
@@ -1304,7 +1309,7 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def,
2daa92
             goto cleanup;
2daa92
     } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) {
2daa92
         /* deal with legacy virtio-s390 */
2daa92
-        qemuDomainPrimeS390VirtioDevices(
2daa92
+        qemuDomainPrimeVirtioDeviceAddresses(
2daa92
             def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390);
2daa92
     }
2daa92
 
Daniel P. Berrange 11755d
@@ -1327,6 +1332,18 @@ cleanup:
2daa92
 
2daa92
     return ret;
2daa92
 }
2daa92
+static int
2daa92
+qemuDomainAssignARMVirtioMMIOAddresses(virDomainDefPtr def,
2daa92
+                                       virQEMUCapsPtr qemuCaps)
2daa92
+{
2daa92
+    if (def->os.arch == VIR_ARCH_ARMV7L &&
2daa92
+        STRPREFIX(def->os.machine, "vexpress-") &&
2daa92
+        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MMIO)) {
2daa92
+        qemuDomainPrimeVirtioDeviceAddresses(
2daa92
+            def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO);
2daa92
+    }
2daa92
+    return 0;
2daa92
+}
2daa92
 
2daa92
 static int
2daa92
 qemuSpaprVIOFindByReg(virDomainDefPtr def ATTRIBUTE_UNUSED,
Daniel P. Berrange 11755d
@@ -1912,6 +1929,10 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
2daa92
     if (rc)
2daa92
         return rc;
2daa92
 
2daa92
+    rc = qemuDomainAssignARMVirtioMMIOAddresses(def, qemuCaps);
2daa92
+    if (rc)
2daa92
+        return rc;
2daa92
+
2daa92
     return qemuDomainAssignPCIAddresses(def, qemuCaps, obj);
2daa92
 }
2daa92
 
Daniel P. Berrange 11755d
@@ -4367,6 +4388,9 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
2daa92
         } else if (disk->info.type ==
2daa92
                    VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
2daa92
             virBufferAddLit(&opt, "virtio-blk-s390");
2daa92
+        } else if (disk->info.type ==
2daa92
+                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
2daa92
+            virBufferAddLit(&opt, "virtio-blk-device");
2daa92
         } else {
2daa92
             virBufferAddLit(&opt, "virtio-blk-pci");
2daa92
         }
Daniel P. Berrange 11755d
@@ -4645,6 +4669,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
2daa92
             else if (def->info.type ==
2daa92
                      VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
2daa92
                 virBufferAddLit(&buf, "virtio-scsi-s390");
2daa92
+            else if (def->info.type ==
2daa92
+                     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
2daa92
+                virBufferAddLit(&buf, "virtio-scsi-device");
2daa92
             else
2daa92
                 virBufferAddLit(&buf, "virtio-scsi-pci");
2daa92
             break;
Daniel P. Berrange 11755d
@@ -4674,6 +4701,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
2daa92
         } else if (def->info.type ==
2daa92
                    VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
2daa92
             virBufferAddLit(&buf, "virtio-serial-s390");
2daa92
+        } else if (def->info.type ==
2daa92
+                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
2daa92
+            virBufferAddLit(&buf, "virtio-serial-device");
2daa92
         } else {
2daa92
             virBufferAddLit(&buf, "virtio-serial");
2daa92
         }
Daniel P. Berrange 11755d
@@ -4806,6 +4836,8 @@ qemuBuildNicDevStr(virDomainDefPtr def,
2daa92
             nic = "virtio-net-ccw";
2daa92
         else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
2daa92
             nic = "virtio-net-s390";
2daa92
+        else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
2daa92
+            nic = "virtio-net-device";
2daa92
         else
2daa92
             nic = "virtio-net-pci";
2daa92
 
Daniel P. Berrange 11755d
@@ -5054,6 +5086,9 @@ qemuBuildMemballoonDevStr(virDomainDefPtr def,
2daa92
         case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW:
2daa92
             virBufferAddLit(&buf, "virtio-balloon-ccw");
2daa92
             break;
2daa92
+        case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
2daa92
+            virBufferAddLit(&buf, "virtio-balloon-device");
2daa92
+            break;
2daa92
         default:
2daa92
             virReportError(VIR_ERR_XML_ERROR,
2daa92
                            _("memballoon unsupported with address type '%s'"),
Daniel P. Berrange 11755d
@@ -6055,6 +6090,8 @@ qemuBuildRNGDeviceArgs(virCommandPtr cmd,
2daa92
         virBufferAsprintf(&buf, "virtio-rng-ccw,rng=%s", dev->info.alias);
2daa92
     else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
2daa92
         virBufferAsprintf(&buf, "virtio-rng-s390,rng=%s", dev->info.alias);
2daa92
+    else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
2daa92
+        virBufferAsprintf(&buf, "virtio-rng-device,rng=%s", dev->info.alias);
2daa92
     else
2daa92
         virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias);
2daa92
 
Daniel P. Berrange 11755d
@@ -7331,7 +7368,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
2daa92
      *
2daa92
      * NB, no support for -netdev without use of -device
2daa92
      */
2daa92
-    if (qemuDomainSupportsNetdev(def, qemuCaps)) {
2daa92
+    if (qemuDomainSupportsNetdev(def, qemuCaps, net)) {
2daa92
         if (!(host = qemuBuildHostNetStr(net, driver,
2daa92
                                          ',', vlan,
2daa92
                                          tapfdName, tapfdSize,
Daniel P. Berrange 11755d
@@ -7339,7 +7376,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
2daa92
             goto cleanup;
2daa92
         virCommandAddArgList(cmd, "-netdev", host, NULL);
2daa92
     }
2daa92
-    if (qemuDomainSupportsNicdev(def, qemuCaps)) {
2daa92
+    if (qemuDomainSupportsNicdev(def, qemuCaps, net)) {
Daniel P. Berrange 11755d
         bool multiqueue = tapfdSize > 1 || vhostfdSize > 1;
Daniel P. Berrange 11755d
 
Daniel P. Berrange 11755d
         if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex,
Daniel P. Berrange 11755d
@@ -7351,7 +7388,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
2daa92
             goto cleanup;
2daa92
         virCommandAddArgList(cmd, "-net", nic, NULL);
2daa92
     }
2daa92
-    if (!qemuDomainSupportsNetdev(def, qemuCaps)) {
2daa92
+    if (!qemuDomainSupportsNetdev(def, qemuCaps, net)) {
2daa92
         if (!(host = qemuBuildHostNetStr(net, driver,
2daa92
                                          ',', vlan,
2daa92
                                          tapfdName, tapfdSize,
Daniel P. Berrange 11755d
@@ -8402,7 +8439,7 @@ qemuBuildCommandLine(virConnectPtr conn,
2daa92
             int vlan;
2daa92
 
2daa92
             /* VLANs are not used with -netdev, so don't record them */
2daa92
-            if (qemuDomainSupportsNetdev(def, qemuCaps))
2daa92
+            if (qemuDomainSupportsNetdev(def, qemuCaps, net))
2daa92
                 vlan = -1;
2daa92
             else
2daa92
                 vlan = i;
2daa92
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args
2daa92
new file mode 100644
2daa92
index 0000000..62de9d3
2daa92
--- /dev/null
2daa92
+++ b/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args
2daa92
@@ -0,0 +1,14 @@
2daa92
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
2daa92
+/usr/bin/qemu-system-arm -S -M vexpress-a9 -m 1024 -smp 1 -nographic \
2daa92
+-nodefconfig -nodefaults -monitor unix:/tmp/test-monitor,server,nowait \
2daa92
+-boot c -kernel /arm.kernel -initrd /arm.initrd -append \
2daa92
+'console=ttyAMA0,115200n8 rw root=/dev/vda3 rootwait physmap.enabled=0' \
2daa92
+-dtb /arm.dtb -device virtio-serial-device,id=virtio-serial0 -usb \
2daa92
+-drive file=/arm.raw,if=none,id=drive-virtio-disk0 \
2daa92
+-device virtio-blk-device,drive=drive-virtio-disk0,id=virtio-disk0 \
2daa92
+-device virtio-net-device,vlan=0,id=net0,mac=52:54:00:09:a4:37 \
2daa92
+-net user,vlan=0,name=hostnet0 -serial pty -chardev pty,id=charconsole1 \
2daa92
+-device virtconsole,chardev=charconsole1,id=console1 \
2daa92
+-device virtio-balloon-device,id=balloon0 \
2daa92
+-object rng-random,id=rng0,filename=/dev/random \
2daa92
+-device virtio-rng-device,rng=rng0
2daa92
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.xml
2daa92
new file mode 100644
2daa92
index 0000000..2acf3c9
2daa92
--- /dev/null
2daa92
+++ b/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.xml
2daa92
@@ -0,0 +1,45 @@
2daa92
+<domain type="qemu">
2daa92
+  <name>armtest</name>
2daa92
+  <uuid>496d7ea8-9739-544b-4ebd-ef08be936e6a</uuid>
2daa92
+  <memory>1048576</memory>
2daa92
+  <currentMemory>1048576</currentMemory>
2daa92
+  <vcpu>1</vcpu>
2daa92
+  <os>
2daa92
+    <type arch="armv7l" machine="vexpress-a9">hvm</type>
2daa92
+    <kernel>/arm.kernel</kernel>
2daa92
+    <initrd>/arm.initrd</initrd>
2daa92
+    <dtb>/arm.dtb</dtb>
2daa92
+    <cmdline>console=ttyAMA0,115200n8 rw root=/dev/vda3 rootwait physmap.enabled=0</cmdline>
2daa92
+  </os>
2daa92
+  <features>
2daa92
+    <acpi/>
2daa92
+    <apic/>
2daa92
+    <pae/>
2daa92
+  </features>
2daa92
+  <clock offset="utc"/>
2daa92
+  <on_poweroff>destroy</on_poweroff>
2daa92
+  <on_reboot>restart</on_reboot>
2daa92
+  <on_crash>restart</on_crash>
2daa92
+  <devices>
2daa92
+    <emulator>/usr/bin/qemu-system-arm</emulator>
2daa92
+    <disk type='file' device='disk'>
2daa92
+      <source file='/arm.raw'/>
2daa92
+      <target dev='vda' bus='virtio'/>
2daa92
+    </disk>
2daa92
+    <interface type='user'>
2daa92
+      <mac address='52:54:00:09:a4:37'/>
2daa92
+      <model type='virtio'/>
2daa92
+    </interface>
2daa92
+    <console type='pty'/>
2daa92
+    <console type='pty'>
2daa92
+      <target type='virtio' port='0'/>
2daa92
+    </console>
2daa92
+    <memballoon model='virtio'/>
2daa92
+    
2daa92
+      This actually doesn't work in practice because vexpress only has
2daa92
+      4 virtio slots available, rng makes 5 -->
2daa92
+    <rng model='virtio'>
2daa92
+      <backend model='random'>/dev/random</backend>
2daa92
+    </rng>
2daa92
+  </devices>
2daa92
+</domain>
2daa92
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
Daniel P. Berrange 11755d
index 6ecabbf..ae8cc3b 100644
2daa92
--- a/tests/qemuxml2argvtest.c
2daa92
+++ b/tests/qemuxml2argvtest.c
Daniel P. Berrange 11755d
@@ -1062,6 +1062,10 @@ mymain(void)
2daa92
     DO_TEST("arm-vexpressa9-basic",
2daa92
             QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DTB,
2daa92
             QEMU_CAPS_DRIVE);
2daa92
+    DO_TEST("arm-vexpressa9-virtio",
2daa92
+            QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DTB,
2daa92
+            QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE_VIRTIO_MMIO,
2daa92
+            QEMU_CAPS_DEVICE_VIRTIO_RNG, QEMU_CAPS_OBJECT_RNG_RANDOM);
2daa92
 
2daa92
     virObjectUnref(driver.config);
2daa92
     virObjectUnref(driver.caps);