提交 731b0f36 编写于 作者: L Laine Stump

qemu: use vfio-pci on commandline when appropriate

The device option for vfio-pci is nearly identical to that for
pci-assign - only the configfd parameter isn't supported (or needed).

Checking for presence of the bootindex parameter is done separately
from constructing the commandline, similar to how it is done for
pci-assign.

This patch contains tests to check for proper commandline
construction. It also includes tests for parser-formatter-parser
roundtrips (xml2xml), because those tests use the same data files, and
would have failed had they been included before now.

qemu: xml/args tests for VFIO hostdev and <interface type='hostdev'/>

These should be squashed in with the patch that adds commandline
handling of vfio (they would fail at any earlier time).
上级 c4f63ef0
...@@ -4345,14 +4345,19 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd, ...@@ -4345,14 +4345,19 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd,
{ {
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
virBufferAddLit(&buf, "pci-assign"); if (dev->source.subsys.u.pci.backend
== VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) {
virBufferAddLit(&buf, "vfio-pci");
} else {
virBufferAddLit(&buf, "pci-assign");
if (configfd && *configfd)
virBufferAsprintf(&buf, ",configfd=%s", configfd);
}
virBufferAsprintf(&buf, ",host=%.2x:%.2x.%.1x", virBufferAsprintf(&buf, ",host=%.2x:%.2x.%.1x",
dev->source.subsys.u.pci.addr.bus, dev->source.subsys.u.pci.addr.bus,
dev->source.subsys.u.pci.addr.slot, dev->source.subsys.u.pci.addr.slot,
dev->source.subsys.u.pci.addr.function); dev->source.subsys.u.pci.addr.function);
virBufferAsprintf(&buf, ",id=%s", dev->info->alias); virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
if (configfd && *configfd)
virBufferAsprintf(&buf, ",configfd=%s", configfd);
if (dev->info->bootIndex) if (dev->info->bootIndex)
virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex); virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
if (qemuBuildDeviceAddressStr(&buf, dev->info, qemuCaps) < 0) if (qemuBuildDeviceAddressStr(&buf, dev->info, qemuCaps) < 0)
...@@ -7846,22 +7851,33 @@ qemuBuildCommandLine(virConnectPtr conn, ...@@ -7846,22 +7851,33 @@ qemuBuildCommandLine(virConnectPtr conn,
(hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)) { hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("booting from assigned devices is only" _("booting from assigned devices is only "
" supported for PCI and USB devices")); "supported for PCI and USB devices"));
goto error; goto error;
} else { } else {
if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_BOOTINDEX)) { if (hostdev->source.subsys.u.pci.backend
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) {
_("booting from assigned PCI devices is not" if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_BOOTINDEX)) {
" supported with this version of qemu")); virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
goto error; _("booting from PCI devices assigned with VFIO "
"is not supported with this version of qemu"));
goto error;
}
} else {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_BOOTINDEX)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("booting from assigned PCI devices is not "
"supported with this version of qemu"));
goto error;
}
}
} }
if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB && if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HOST_BOOTINDEX)) { !virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HOST_BOOTINDEX)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("booting from assigned USB devices is not" _("booting from assigned USB devices is not "
" supported with this version of qemu")); "supported with this version of qemu"));
goto error; goto error;
} }
} }
...@@ -7889,9 +7905,21 @@ qemuBuildCommandLine(virConnectPtr conn, ...@@ -7889,9 +7905,21 @@ qemuBuildCommandLine(virConnectPtr conn,
/* PCI */ /* PCI */
if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
if ((hostdev->source.subsys.u.pci.backend
== VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("VFIO PCI device assignment is not supported by "
"this version of qemu"));
goto error;
}
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
char *configfd_name = NULL; char *configfd_name = NULL;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) { if ((hostdev->source.subsys.u.pci.backend
!= VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
int configfd = qemuOpenPCIConfig(hostdev); int configfd = qemuOpenPCIConfig(hostdev);
if (configfd >= 0) { if (configfd >= 0) {
......
...@@ -999,13 +999,24 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver, ...@@ -999,13 +999,24 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
&hostdev, 1) < 0) &hostdev, 1) < 0)
return -1; return -1;
if ((hostdev->source.subsys.u.pci.backend
== VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("VFIO PCI device assignment is not supported by "
"this version of qemu"));
goto error;
}
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0) if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
goto error; goto error;
if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0) if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0)
goto error; goto error;
releaseaddr = true; releaseaddr = true;
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) { if ((hostdev->source.subsys.u.pci.backend
!= VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
configfd = qemuOpenPCIConfig(hostdev); configfd = qemuOpenPCIConfig(hostdev);
if (configfd >= 0) { if (configfd >= 0) {
if (virAsprintf(&configfd_name, "fd-%s", if (virAsprintf(&configfd_name, "fd-%s",
......
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \
unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb -hda \
/dev/HostVG/QEMUGuest2 -device vfio-pci,host=06:12.5,id=hostdev0,\
bus=pci.0,addr=0x3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
<domain type='qemu'>
<name>QEMUGuest2</name>
<uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest2'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<controller type='usb' index='0'/>
<controller type='ide' index='0'/>
<controller type='pci' index='0' model='pci-root'/>
<hostdev mode='subsystem' type='pci' managed='yes'>
<driver name='vfio'/>
<source>
<address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
</source>
</hostdev>
<memballoon model='virtio'/>
</devices>
</domain>
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \
-M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \
unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
-usb -hda /dev/HostVG/QEMUGuest1 \
-device vfio-pci,host=03:07.1,id=hostdev0,bus=pci.0,addr=0x3 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
</disk>
<controller type='usb' index='0'/>
<controller type='ide' index='0'/>
<controller type='pci' index='0' model='pci-root'/>
<interface type='hostdev' managed='yes'>
<mac address='00:11:22:33:44:55'/>
<driver name='vfio'/>
<source>
<address type='pci' domain='0x0002' bus='0x03' slot='0x07' function='0x1'/>
</source>
<vlan>
<tag id='42'/>
</vlan>
<virtualport type='802.1Qbg'>
<parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
</virtualport>
<model type='rtl8139'/>
</interface>
<memballoon model='virtio'/>
</devices>
</domain>
...@@ -672,6 +672,9 @@ mymain(void) ...@@ -672,6 +672,9 @@ mymain(void)
DO_TEST("net-mcast", NONE); DO_TEST("net-mcast", NONE);
DO_TEST("net-hostdev", DO_TEST("net-hostdev",
QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
DO_TEST("net-hostdev-vfio",
QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_DEVICE_VFIO_PCI);
DO_TEST("serial-vc", NONE); DO_TEST("serial-vc", NONE);
DO_TEST("serial-pty", NONE); DO_TEST("serial-pty", NONE);
...@@ -834,6 +837,9 @@ mymain(void) ...@@ -834,6 +837,9 @@ mymain(void)
DO_TEST("hostdev-pci-address", QEMU_CAPS_PCIDEVICE); DO_TEST("hostdev-pci-address", QEMU_CAPS_PCIDEVICE);
DO_TEST("hostdev-pci-address-device", DO_TEST("hostdev-pci-address-device",
QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
DO_TEST("hostdev-vfio",
QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_DEVICE_VFIO_PCI);
DO_TEST("pci-rom", DO_TEST("pci-rom",
QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_PCI_ROMBAR); QEMU_CAPS_PCI_ROMBAR);
......
...@@ -208,6 +208,7 @@ mymain(void) ...@@ -208,6 +208,7 @@ mymain(void)
DO_TEST("net-eth-ifname"); DO_TEST("net-eth-ifname");
DO_TEST("net-virtio-network-portgroup"); DO_TEST("net-virtio-network-portgroup");
DO_TEST("net-hostdev"); DO_TEST("net-hostdev");
DO_TEST("net-hostdev-vfio");
DO_TEST("net-openvswitch"); DO_TEST("net-openvswitch");
DO_TEST("sound"); DO_TEST("sound");
DO_TEST("sound-device"); DO_TEST("sound-device");
...@@ -230,6 +231,7 @@ mymain(void) ...@@ -230,6 +231,7 @@ mymain(void)
DO_TEST("hostdev-usb-address"); DO_TEST("hostdev-usb-address");
DO_TEST("hostdev-pci-address"); DO_TEST("hostdev-pci-address");
DO_TEST("hostdev-vfio");
DO_TEST("pci-rom"); DO_TEST("pci-rom");
DO_TEST("encrypted-disk"); DO_TEST("encrypted-disk");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册