qemu: Support virtio-mmio transport for virtio on ARM

Starting with qemu 1.6, the qemu-system-arm vexpress-a9 model has a
hardcoded virtio-mmio transport which enables attaching all virtio
devices.

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.
This commit is contained in:
Cole Robinson 2013-07-31 21:40:35 -04:00
parent 54a77c6df3
commit 4fa172215d
8 changed files with 137 additions and 21 deletions

View File

@ -210,7 +210,8 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"usb", "usb",
"spapr-vio", "spapr-vio",
"virtio-s390", "virtio-s390",
"ccw") "ccw",
"virtio-mmio")
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST, VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
"block", "block",
@ -2390,6 +2391,7 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info,
return 1; return 1;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390: case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390:
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
return 1; return 1;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW:
@ -3031,6 +3033,9 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
info->addr.ccw.devno); info->addr.ccw.devno);
break; break;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
break;
default: default:
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown address type '%d'"), info->type); _("unknown address type '%d'"), info->type);
@ -3495,6 +3500,9 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
goto cleanup; goto cleanup;
break; break;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
break;
default: default:
/* Should not happen */ /* Should not happen */
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
@ -5848,6 +5856,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO && 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_CCW &&
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 && 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) { def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Controllers must use the 'pci' address type")); _("Controllers must use the 'pci' address type"));
@ -6408,6 +6417,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO && 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_CCW &&
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 && 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) { def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Network interfaces must use 'pci' address type")); _("Network interfaces must use 'pci' address type"));

View File

@ -207,6 +207,7 @@ enum virDomainDeviceAddressType {
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
}; };

View File

@ -240,6 +240,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"usb-storage", /* 155 */ "usb-storage", /* 155 */
"usb-storage.removable", "usb-storage.removable",
"virtio-mmio",
); );
struct _virQEMUCaps { struct _virQEMUCaps {
@ -1389,6 +1390,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "scsi-generic", QEMU_CAPS_DEVICE_SCSI_GENERIC }, { "scsi-generic", QEMU_CAPS_DEVICE_SCSI_GENERIC },
{ "i82801b11-bridge", QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE }, { "i82801b11-bridge", QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE },
{ "usb-storage", QEMU_CAPS_DEVICE_USB_STORAGE }, { "usb-storage", QEMU_CAPS_DEVICE_USB_STORAGE },
{ "virtio-mmio", QEMU_CAPS_DEVICE_VIRTIO_MMIO },
}; };
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = { static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = {
@ -2842,17 +2844,19 @@ virQEMUCapsUsedQMP(virQEMUCapsPtr qemuCaps)
bool bool
virQEMUCapsSupportsChardev(virDomainDefPtr def, virQEMUCapsSupportsChardev(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps, virQEMUCapsPtr qemuCaps,
virDomainChrDefPtr chr ATTRIBUTE_UNUSED) virDomainChrDefPtr chr)
{ {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) || if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
return false; return false;
/* This may not be true for all ARM machine types, but at least
* the only supported serial devices of vexpress and versatile
* don't have the -chardev property wired up. */
if (def->os.arch != VIR_ARCH_ARMV7L) 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 only supported non-virtio serial devices of vexpress and versatile
* 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));
} }

View File

@ -195,6 +195,7 @@ enum virQEMUCapsFlags {
QEMU_CAPS_Q35_PCI_HOLE64_SIZE = 154, /* q35-pcihost.pci-hole64-size */ QEMU_CAPS_Q35_PCI_HOLE64_SIZE = 154, /* q35-pcihost.pci-hole64-size */
QEMU_CAPS_DEVICE_USB_STORAGE = 155, /* -device usb-storage */ QEMU_CAPS_DEVICE_USB_STORAGE = 155, /* -device usb-storage */
QEMU_CAPS_USB_STORAGE_REMOVABLE = 156, /* usb-storage.removable */ QEMU_CAPS_USB_STORAGE_REMOVABLE = 156, /* usb-storage.removable */
QEMU_CAPS_DEVICE_VIRTIO_MMIO = 157, /* -device virtio-mmio */
QEMU_CAPS_LAST, /* this must always be the last item */ QEMU_CAPS_LAST, /* this must always be the last item */
}; };

View File

@ -418,22 +418,27 @@ cleanup:
} }
static bool static bool
qemuDomainSupportsNicdev(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) qemuDomainSupportsNicdev(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
virDomainNetDefPtr net)
{ {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
return false; return false;
/* arm boards require legacy -net nic */ /* non-virtio ARM nics require legacy -net nic */
if (def->os.arch == VIR_ARCH_ARMV7L) if (def->os.arch == VIR_ARCH_ARMV7L &&
net->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
return false; return false;
return true; return true;
} }
static bool 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 false;
return virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV); return virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV);
} }
@ -474,7 +479,7 @@ qemuOpenVhostNet(virDomainDefPtr def,
* option), don't try to open the device. * option), don't try to open the device.
*/ */
if (!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOST_NET) && 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) { if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("vhost-net is not supported with " "%s", _("vhost-net is not supported with "
@ -1154,8 +1159,8 @@ cleanup:
} }
static void static void
qemuDomainPrimeS390VirtioDevices(virDomainDefPtr def, qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
enum virDomainDeviceAddressType type) enum virDomainDeviceAddressType type)
{ {
/* /*
declare address-less virtio devices to be of address type 'type' declare address-less virtio devices to be of address type 'type'
@ -1289,7 +1294,7 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def,
if (STREQLEN(def->os.machine, "s390-ccw", 8) && if (STREQLEN(def->os.machine, "s390-ccw", 8) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_CCW)) { virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
qemuDomainPrimeS390VirtioDevices( qemuDomainPrimeVirtioDeviceAddresses(
def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW); def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW);
if (!(addrs = qemuDomainCCWAddressSetCreate())) if (!(addrs = qemuDomainCCWAddressSetCreate()))
@ -1304,7 +1309,7 @@ qemuDomainAssignS390Addresses(virDomainDefPtr def,
goto cleanup; goto cleanup;
} else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) { } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) {
/* deal with legacy virtio-s390 */ /* deal with legacy virtio-s390 */
qemuDomainPrimeS390VirtioDevices( qemuDomainPrimeVirtioDeviceAddresses(
def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390); def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390);
} }
@ -1327,6 +1332,18 @@ cleanup:
return ret; return ret;
} }
static int
qemuDomainAssignARMVirtioMMIOAddresses(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps)
{
if (def->os.arch == VIR_ARCH_ARMV7L &&
STRPREFIX(def->os.machine, "vexpress-") &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MMIO)) {
qemuDomainPrimeVirtioDeviceAddresses(
def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO);
}
return 0;
}
static int static int
qemuSpaprVIOFindByReg(virDomainDefPtr def ATTRIBUTE_UNUSED, qemuSpaprVIOFindByReg(virDomainDefPtr def ATTRIBUTE_UNUSED,
@ -1912,6 +1929,10 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
if (rc) if (rc)
return rc; return rc;
rc = qemuDomainAssignARMVirtioMMIOAddresses(def, qemuCaps);
if (rc)
return rc;
return qemuDomainAssignPCIAddresses(def, qemuCaps, obj); return qemuDomainAssignPCIAddresses(def, qemuCaps, obj);
} }
@ -4367,6 +4388,9 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
} else if (disk->info.type == } else if (disk->info.type ==
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
virBufferAddLit(&opt, "virtio-blk-s390"); virBufferAddLit(&opt, "virtio-blk-s390");
} else if (disk->info.type ==
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
virBufferAddLit(&opt, "virtio-blk-device");
} else { } else {
virBufferAddLit(&opt, "virtio-blk-pci"); virBufferAddLit(&opt, "virtio-blk-pci");
} }
@ -4668,6 +4692,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
else if (def->info.type == else if (def->info.type ==
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
virBufferAddLit(&buf, "virtio-scsi-s390"); virBufferAddLit(&buf, "virtio-scsi-s390");
else if (def->info.type ==
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
virBufferAddLit(&buf, "virtio-scsi-device");
else else
virBufferAddLit(&buf, "virtio-scsi-pci"); virBufferAddLit(&buf, "virtio-scsi-pci");
break; break;
@ -4697,6 +4724,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
} else if (def->info.type == } else if (def->info.type ==
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
virBufferAddLit(&buf, "virtio-serial-s390"); virBufferAddLit(&buf, "virtio-serial-s390");
} else if (def->info.type ==
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
virBufferAddLit(&buf, "virtio-serial-device");
} else { } else {
virBufferAddLit(&buf, "virtio-serial"); virBufferAddLit(&buf, "virtio-serial");
} }
@ -4829,6 +4859,8 @@ qemuBuildNicDevStr(virDomainDefPtr def,
nic = "virtio-net-ccw"; nic = "virtio-net-ccw";
else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
nic = "virtio-net-s390"; nic = "virtio-net-s390";
else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
nic = "virtio-net-device";
else else
nic = "virtio-net-pci"; nic = "virtio-net-pci";
@ -5077,6 +5109,9 @@ qemuBuildMemballoonDevStr(virDomainDefPtr def,
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW:
virBufferAddLit(&buf, "virtio-balloon-ccw"); virBufferAddLit(&buf, "virtio-balloon-ccw");
break; break;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
virBufferAddLit(&buf, "virtio-balloon-device");
break;
default: default:
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("memballoon unsupported with address type '%s'"), _("memballoon unsupported with address type '%s'"),
@ -6078,6 +6113,8 @@ qemuBuildRNGDeviceArgs(virCommandPtr cmd,
virBufferAsprintf(&buf, "virtio-rng-ccw,rng=%s", dev->info.alias); virBufferAsprintf(&buf, "virtio-rng-ccw,rng=%s", dev->info.alias);
else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
virBufferAsprintf(&buf, "virtio-rng-s390,rng=%s", dev->info.alias); 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 else
virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias); virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias);
@ -7354,7 +7391,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
* *
* NB, no support for -netdev without use of -device * NB, no support for -netdev without use of -device
*/ */
if (qemuDomainSupportsNetdev(def, qemuCaps)) { if (qemuDomainSupportsNetdev(def, qemuCaps, net)) {
if (!(host = qemuBuildHostNetStr(net, driver, if (!(host = qemuBuildHostNetStr(net, driver,
',', vlan, ',', vlan,
tapfdName, tapfdSize, tapfdName, tapfdSize,
@ -7362,7 +7399,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
goto cleanup; goto cleanup;
virCommandAddArgList(cmd, "-netdev", host, NULL); virCommandAddArgList(cmd, "-netdev", host, NULL);
} }
if (qemuDomainSupportsNicdev(def, qemuCaps)) { if (qemuDomainSupportsNicdev(def, qemuCaps, net)) {
bool multiqueue = tapfdSize > 1 || vhostfdSize > 1; bool multiqueue = tapfdSize > 1 || vhostfdSize > 1;
if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex, if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex,
@ -7374,7 +7411,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
goto cleanup; goto cleanup;
virCommandAddArgList(cmd, "-net", nic, NULL); virCommandAddArgList(cmd, "-net", nic, NULL);
} }
if (!qemuDomainSupportsNetdev(def, qemuCaps)) { if (!qemuDomainSupportsNetdev(def, qemuCaps, net)) {
if (!(host = qemuBuildHostNetStr(net, driver, if (!(host = qemuBuildHostNetStr(net, driver,
',', vlan, ',', vlan,
tapfdName, tapfdSize, tapfdName, tapfdSize,
@ -8425,7 +8462,7 @@ qemuBuildCommandLine(virConnectPtr conn,
int vlan; int vlan;
/* VLANs are not used with -netdev, so don't record them */ /* VLANs are not used with -netdev, so don't record them */
if (qemuDomainSupportsNetdev(def, qemuCaps)) if (qemuDomainSupportsNetdev(def, qemuCaps, net))
vlan = -1; vlan = -1;
else else
vlan = i; vlan = i;

View File

@ -0,0 +1,14 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
/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 /arm.dtb -device virtio-serial-device,id=virtio-serial0 -usb \
-drive file=/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

View File

@ -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>/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='/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>

View File

@ -1066,6 +1066,10 @@ mymain(void)
DO_TEST("arm-vexpressa9-basic", DO_TEST("arm-vexpressa9-basic",
QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DTB, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DTB,
QEMU_CAPS_DRIVE); 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.config);
virObjectUnref(driver.caps); virObjectUnref(driver.caps);