On 07/31/2013 10:14 PM, Cole Robinson wrote: > Starting with qemu 1.6, the qemu-system-arm vexpress-a9 model has a > hardcoded virtio-mmio transport which enables attaching all virtio > devices. Okay, so there is something named "virtio-mmio" that is visible in the qemu capabilities; it isn't added to the commandline anywhere, but its presence means that all the virtio devices are available with the suffix ...-device rather than ...-device-whatever. A bit strange, but if that's the way it works, that's the way it works... This all looks okay to me, but somebody else should look too, as it's getting pretty late here and I'm not certain I'm completely alert :-) > > On the command line, we have to use virtio-XXX-device rather than > virtio-XXX-pci, thankfully s390 already set the precedent here so > it's fairly straight forward. > > At the XML level, this adds a new device address type virtio-mmio. > The controller and addressing don't have any subelements at the > moment because we they aren't needed for this usecase, but could > be added later if needed. > > Add a test case for an ARM guest with one of every virtio device > enabled. > --- > src/conf/domain_conf.c | 12 +++- > src/conf/domain_conf.h | 1 + > src/qemu/qemu_capabilities.c | 16 ++++-- > src/qemu/qemu_capabilities.h | 1 + > src/qemu/qemu_command.c | 65 +++++++++++++++++----- > .../qemuxml2argv-arm-vexpressa9-virtio.args | 1 + > .../qemuxml2argv-arm-vexpressa9-virtio.xml | 45 +++++++++++++++ > tests/qemuxml2argvtest.c | 4 ++ > 8 files changed, 124 insertions(+), 21 deletions(-) > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.xml > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 5e423cc..25d356b 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -210,7 +210,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, > "usb", > "spapr-vio", > "virtio-s390", > - "ccw") > + "ccw", > + "virtio-mmio") > > VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST, > "block", > @@ -2386,6 +2387,7 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, > return 1; > > case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390: > + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO: > return 1; > > case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: > @@ -3027,6 +3029,9 @@ virDomainDeviceInfoFormat(virBufferPtr buf, > info->addr.ccw.devno); > break; > > + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO: > + break; > + > default: > virReportError(VIR_ERR_INTERNAL_ERROR, > _("unknown address type '%d'"), info->type); > @@ -3491,6 +3496,9 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, > goto cleanup; > break; > > + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO: > + break; > + > default: > /* Should not happen */ > virReportError(VIR_ERR_INTERNAL_ERROR, > @@ -5738,6 +5746,7 @@ virDomainControllerDefParseXML(xmlNodePtr node, > def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO && > def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && > def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 && > + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO && > def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { > virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > _("Controllers must use the 'pci' address type")); > @@ -6349,6 +6358,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, > def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO && > def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && > def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 && > + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO && > def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { > virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > _("Network interfaces must use 'pci' address type")); > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index 978be16..4d90f84 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -207,6 +207,7 @@ enum virDomainDeviceAddressType { > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO, > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390, > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW, > + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO, > > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST > }; > diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c > index 51064e8..2b0e9fc 100644 > --- a/src/qemu/qemu_capabilities.c > +++ b/src/qemu/qemu_capabilities.c > @@ -234,6 +234,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, > > "vnc-share-policy", /* 150 */ > "device-del-event", > + "virtio-mmio", > ); > > struct _virQEMUCaps { > @@ -1381,6 +1382,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { > { "pci-bridge", QEMU_CAPS_DEVICE_PCI_BRIDGE }, > { "vfio-pci", QEMU_CAPS_DEVICE_VFIO_PCI }, > { "scsi-generic", QEMU_CAPS_DEVICE_SCSI_GENERIC }, > + { "virtio-mmio", QEMU_CAPS_DEVICE_VIRTIO_MMIO }, > }; > > static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = { > @@ -2814,17 +2816,19 @@ virQEMUCapsUsedQMP(virQEMUCapsPtr qemuCaps) > bool > virQEMUCapsSupportsChardev(virDomainDefPtr def, > virQEMUCapsPtr qemuCaps, > - virDomainChrDefPtr chr ATTRIBUTE_UNUSED) > + virDomainChrDefPtr chr) > { > if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) || > !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) > return false; > > - /* This may not be true for all machine types, but at least > - * the only supported serial devices of vexpress-a9 and versatilepb > - * don't have the chardev property wired up */ > if (def->os.arch != VIR_ARCH_ARMV7L) > - return false; > + return true; > > - return true; > + /* This may not be true for all ARM machine types, but at least > + * the non-virtio serial devices of vexpress-a9 and versatilepb > + * don't have the chardev property wired up */ > + return (chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO || > + (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE && > + chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO)); > } > diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h > index 56f8405..fdb61b0 100644 > --- a/src/qemu/qemu_capabilities.h > +++ b/src/qemu/qemu_capabilities.h > @@ -190,6 +190,7 @@ enum virQEMUCapsFlags { > QEMU_CAPS_MLOCK = 149, /* -realtime mlock=on|off */ > QEMU_CAPS_VNC_SHARE_POLICY = 150, /* set display sharing policy */ > QEMU_CAPS_DEVICE_DEL_EVENT = 151, /* DEVICE_DELETED event */ > + QEMU_CAPS_DEVICE_VIRTIO_MMIO = 152, /* -device virtio-mmio */ > > QEMU_CAPS_LAST, /* this must always be the last item */ > }; > diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c > index f611940..9b037f5 100644 > --- a/src/qemu/qemu_command.c > +++ b/src/qemu/qemu_command.c > @@ -418,22 +418,27 @@ cleanup: > } > > static bool > -qemuDomainSupportsNicdev(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) > +qemuDomainSupportsNicdev(virDomainDefPtr def, > + virQEMUCapsPtr qemuCaps, > + virDomainNetDefPtr net) > { > if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) > return false; > > - /* arm boards require legacy -net nic */ > - if (def->os.arch == VIR_ARCH_ARMV7L) > + /* non-virtio ARM nics require legacy -net nic */ > + if (def->os.arch == VIR_ARCH_ARMV7L && > + net->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) > return false; Urgh. Now I see why this shouldn't be put in qemu_capabilities.c :-/ > > return true; > } > > static bool > -qemuDomainSupportsNetdev(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) > +qemuDomainSupportsNetdev(virDomainDefPtr def, > + virQEMUCapsPtr qemuCaps, > + virDomainNetDefPtr net) > { > - if (!qemuDomainSupportsNicdev(def, qemuCaps)) > + if (!qemuDomainSupportsNicdev(def, qemuCaps, net)) > return false; > return virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV); > } > @@ -474,7 +479,7 @@ qemuOpenVhostNet(virDomainDefPtr def, > * option), don't try to open the device. > */ > if (!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOST_NET) && > - qemuDomainSupportsNetdev(def, qemuCaps))) { > + qemuDomainSupportsNetdev(def, qemuCaps, net))) { > if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) { > virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > "%s", _("vhost-net is not supported with " > @@ -1146,8 +1151,8 @@ cleanup: > } > > static void > -qemuDomainPrimeS390VirtioDevices(virDomainDefPtr def, > - enum virDomainDeviceAddressType type) > +qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def, > + enum virDomainDeviceAddressType type) > { > /* > declare address-less virtio devices to be of address type 'type' > @@ -1281,7 +1286,7 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def, > > if (STREQLEN(def->os.machine, "s390-ccw", 8) && > virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_CCW)) { > - qemuDomainPrimeS390VirtioDevices( > + qemuDomainPrimeVirtioDeviceAddresses( > def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW); > > if (!(addrs = qemuDomainCCWAddressSetCreate())) > @@ -1296,7 +1301,7 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def, > goto cleanup; > } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) { > /* deal with legacy virtio-s390 */ > - qemuDomainPrimeS390VirtioDevices( > + qemuDomainPrimeVirtioDeviceAddresses( > def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390); > } > > @@ -1319,6 +1324,18 @@ cleanup: > > return ret; > } > +static int > +qemuDomainAssignARMVirtioMMIOAddresses(virDomainDefPtr def, > + virQEMUCapsPtr qemuCaps) Does this really need to be arm-specific? Isn't is possible that there would be other machines/arches that also have a virtio-mmio controller built-in, and user the virtio-xxx-device devices? Maybe this function needs a more generic name, and to just check QEMU_CAPS_DEVICE_VIRTIO_MMIO, rather than adding in the check for os.arch and os.machine. > +{ > + if (def->os.arch == VIR_ARCH_ARMV7L && > + STREQ(def->os.machine, "vexpress-a9") && > + virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MMIO)) { > + qemuDomainPrimeVirtioDeviceAddresses( > + def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO); > + } > + return 0; > +} > > static int > qemuSpaprVIOFindByReg(virDomainDefPtr def ATTRIBUTE_UNUSED, > @@ -1833,6 +1850,10 @@ int qemuDomainAssignAddresses(virDomainDefPtr def, > if (rc) > return rc; > > + rc = qemuDomainAssignARMVirtioMMIOAddresses(def, qemuCaps); > + if (rc) > + return rc; > + > return qemuDomainAssignPCIAddresses(def, qemuCaps, obj); > } > > @@ -3939,6 +3960,9 @@ qemuBuildDriveDevStr(virDomainDefPtr def, > } else if (disk->info.type == > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) { > virBufferAddLit(&opt, "virtio-blk-s390"); > + } else if (disk->info.type == > + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) { > + virBufferAddLit(&opt, "virtio-blk-device"); > } else { > virBufferAddLit(&opt, "virtio-blk-pci"); > } > @@ -4216,6 +4240,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, > else if (def->info.type == > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) > virBufferAddLit(&buf, "virtio-scsi-s390"); > + else if (def->info.type == > + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) > + virBufferAddLit(&buf, "virtio-scsi-device"); > else > virBufferAddLit(&buf, "virtio-scsi-pci"); > break; > @@ -4245,6 +4272,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, > } else if (def->info.type == > VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) { > virBufferAddLit(&buf, "virtio-serial-s390"); > + } else if (def->info.type == > + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) { > + virBufferAddLit(&buf, "virtio-serial-device"); > } else { > virBufferAddLit(&buf, "virtio-serial"); > } > @@ -4360,6 +4390,8 @@ qemuBuildNicDevStr(virDomainNetDefPtr net, > nic = "virtio-net-ccw"; > else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) > nic = "virtio-net-s390"; > + else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) > + nic = "virtio-net-device"; > else > nic = "virtio-net-pci"; > > @@ -4604,6 +4636,9 @@ qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev, > case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: > virBufferAddLit(&buf, "virtio-balloon-ccw"); > break; > + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO: > + virBufferAddLit(&buf, "virtio-balloon-device"); > + break; > default: > virReportError(VIR_ERR_XML_ERROR, > _("memballoon unsupported with address type '%s'"), > @@ -5597,6 +5632,8 @@ qemuBuildRNGDeviceArgs(virCommandPtr cmd, > virBufferAsprintf(&buf, "virtio-rng-ccw,rng=%s", dev->info.alias); > else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) > virBufferAsprintf(&buf, "virtio-rng-s390,rng=%s", dev->info.alias); > + else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) > + virBufferAsprintf(&buf, "virtio-rng-device,rng=%s", dev->info.alias); > else > virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias); > > @@ -6873,7 +6910,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, > * > * NB, no support for -netdev without use of -device > */ > - if (qemuDomainSupportsNetdev(def, qemuCaps)) { > + if (qemuDomainSupportsNetdev(def, qemuCaps, net)) { > if (!(host = qemuBuildHostNetStr(net, driver, > ',', vlan, > tapfdName, tapfdSize, > @@ -6881,7 +6918,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, > goto cleanup; > virCommandAddArgList(cmd, "-netdev", host, NULL); > } > - if (qemuDomainSupportsNicdev(def, qemuCaps)) { > + if (qemuDomainSupportsNicdev(def, qemuCaps, net)) { > if (!(nic = qemuBuildNicDevStr(net, vlan, bootindex, qemuCaps))) > goto cleanup; > virCommandAddArgList(cmd, "-device", nic, NULL); > @@ -6890,7 +6927,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, > goto cleanup; > virCommandAddArgList(cmd, "-net", nic, NULL); > } > - if (!qemuDomainSupportsNetdev(def, qemuCaps)) { > + if (!qemuDomainSupportsNetdev(def, qemuCaps, net)) { > if (!(host = qemuBuildHostNetStr(net, driver, > ',', vlan, > tapfdName, tapfdSize, > @@ -7883,7 +7920,7 @@ qemuBuildCommandLine(virConnectPtr conn, > int vlan; > > /* VLANs are not used with -netdev, so don't record them */ > - if (qemuDomainSupportsNetdev(def, qemuCaps)) > + if (qemuDomainSupportsNetdev(def, qemuCaps, net)) > vlan = -1; > else > vlan = i; > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args > new file mode 100644 > index 0000000..349c758 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args > @@ -0,0 +1 @@ > +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-system-arm -S -M vexpress-a9 -m 1024 -smp 1 -nographic -nodefconfig -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -boot c -kernel /arm-kernel -initrd /arm-initrd -append 'console=ttyAMA0,115200n8 rw root=/dev/vda3 rootwait physmap.enabled=0' -dtb /f19-arm.dtb -device virtio-serial-device,id=virtio-serial0 -drive file=/mnt/data/devel/images/f19-arm.raw,if=none,id=drive-virtio-disk0 -device virtio-blk-device,drive=drive-virtio-disk0,id=virtio-disk0 -device virtio-net-device,vlan=0,id=net0,mac=52:54:00:09:a4:37 -net user,vlan=0,name=hostnet0 -serial pty -chardev pty,id=charconsole1 -device virtconsole,chardev=charconsole1,id=console1 -device virtio-balloon-device,id=balloon0 -object rng-random,id=rng0,filename=/dev/random -device virtio-rng-device,rng=rng0 > diff --git a/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.xml > new file mode 100644 > index 0000000..7709db9 > --- /dev/null > +++ b/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.xml > @@ -0,0 +1,45 @@ > +<domain type="qemu"> > + <name>armtest</name> > + <uuid>496d7ea8-9739-544b-4ebd-ef08be936e6a</uuid> > + <memory>1048576</memory> > + <currentMemory>1048576</currentMemory> > + <vcpu>1</vcpu> > + <os> > + <type arch="armv7l" machine="vexpress-a9">hvm</type> > + <kernel>/arm-kernel</kernel> > + <initrd>/arm-initrd</initrd> > + <dtb>/f19-arm.dtb</dtb> > + <cmdline>console=ttyAMA0,115200n8 rw root=/dev/vda3 rootwait physmap.enabled=0</cmdline> > + </os> > + <features> > + <acpi/> > + <apic/> > + <pae/> > + </features> > + <clock offset="utc"/> > + <on_poweroff>destroy</on_poweroff> > + <on_reboot>restart</on_reboot> > + <on_crash>restart</on_crash> > + <devices> > + <emulator>/usr/bin/qemu-system-arm</emulator> > + <disk type='file' device='disk'> > + <source file='/mnt/data/devel/images/f19-arm.raw'/> > + <target dev='vda' bus='virtio'/> > + </disk> > + <interface type='user'> > + <mac address='52:54:00:09:a4:37'/> > + <model type='virtio'/> > + </interface> > + <console type='pty'/> > + <console type='pty'> > + <target type='virtio' port='0'/> > + </console> > + <memballoon model='virtio'/> > + <!-- > + This actually doesn't work in practice because vexpress only has > + 4 virtio slots available, rng makes 5 --> > + <rng model='virtio'> > + <backend model='random'>/dev/random</backend> > + </rng> > + </devices> > +</domain> > diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c > index 0bf2724..2bdd18e 100644 > --- a/tests/qemuxml2argvtest.c > +++ b/tests/qemuxml2argvtest.c > @@ -1032,6 +1032,10 @@ mymain(void) > DO_TEST("arm-vexpressa9-basic", > QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DTB, > QEMU_CAPS_DRIVE); > + DO_TEST("arm-vexpressa9-virtio", > + QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DTB, > + QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE_VIRTIO_MMIO, > + QEMU_CAPS_DEVICE_VIRTIO_RNG, QEMU_CAPS_OBJECT_RNG_RANDOM); > > virObjectUnref(driver.config); > virObjectUnref(driver.caps); -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list