qemu: hostdev: Refactor PCI passhrough handling

To simplify future patches dealing with this code, simplify and refactor
some conditions to switch statements.
This commit is contained in:
Peter Krempa 2013-09-19 16:48:23 +02:00
parent eee6eb666c
commit 9d13298901
2 changed files with 34 additions and 20 deletions

View File

@ -5485,14 +5485,25 @@ qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
{ {
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
if (dev->source.subsys.u.pci.backend switch ((virDomainHostdevSubsysPciBackendType)
== VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { dev->source.subsys.u.pci.backend) {
virBufferAddLit(&buf, "vfio-pci"); case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
} else { case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
virBufferAddLit(&buf, "pci-assign"); virBufferAddLit(&buf, "pci-assign");
if (configfd && *configfd) if (configfd && *configfd)
virBufferAsprintf(&buf, ",configfd=%s", configfd); virBufferAsprintf(&buf, ",configfd=%s", configfd);
break;
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
virBufferAddLit(&buf, "vfio-pci");
break;
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("PCI passhthrough type needs to be specified"));
break;
} }
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,
@ -9232,7 +9243,6 @@ qemuBuildCommandLine(virConnectPtr conn,
VIR_FREE(devstr); VIR_FREE(devstr);
} }
/* Add host passthrough hardware */ /* Add host passthrough hardware */
for (i = 0; i < def->nhostdevs; i++) { for (i = 0; i < def->nhostdevs; i++) {
virDomainHostdevDefPtr hostdev = def->hostdevs[i]; virDomainHostdevDefPtr hostdev = def->hostdevs[i];
@ -9305,9 +9315,9 @@ 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) {
int backend = hostdev->source.subsys.u.pci.backend;
if (hostdev->source.subsys.u.pci.backend if (backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
== VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("VFIO PCI device assignment is not " _("VFIO PCI device assignment is not "
@ -9321,8 +9331,7 @@ qemuBuildCommandLine(virConnectPtr conn,
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
char *configfd_name = NULL; char *configfd_name = NULL;
if ((hostdev->source.subsys.u.pci.backend if ((backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) &&
!= VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) { virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
int configfd = qemuOpenPCIConfig(hostdev); int configfd = qemuOpenPCIConfig(hostdev);

View File

@ -1134,6 +1134,7 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
int configfd = -1; int configfd = -1;
char *configfd_name = NULL; char *configfd_name = NULL;
bool releaseaddr = false; bool releaseaddr = false;
int backend = hostdev->source.subsys.u.pci.backend;
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0) if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
return -1; return -1;
@ -1142,10 +1143,8 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
&hostdev, 1) < 0) &hostdev, 1) < 0)
return -1; return -1;
if (hostdev->source.subsys.u.pci.backend switch ((virDomainHostdevSubsysPciBackendType) backend) {
== VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
unsigned long long memKB;
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) { if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("VFIO PCI device assignment is not " _("VFIO PCI device assignment is not "
@ -1157,11 +1156,18 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
* In this case, the guest's memory may already be locked, but it * In this case, the guest's memory may already be locked, but it
* doesn't hurt to "change" the limit to the same value. * doesn't hurt to "change" the limit to the same value.
*/ */
vm->def->hostdevs[vm->def->nhostdevs++] = hostdev; if (vm->def->mem.hard_limit)
memKB = vm->def->mem.hard_limit ? virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit);
vm->def->mem.hard_limit : vm->def->mem.max_balloon + 1024 * 1024; else
virProcessSetMaxMemLock(vm->pid, memKB); virProcessSetMaxMemLock(vm->pid,
vm->def->hostdevs[vm->def->nhostdevs--] = NULL; vm->def->mem.max_balloon + (1024 * 1024));
break;
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
break;
} }
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
@ -1170,8 +1176,7 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0) if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0)
goto error; goto error;
releaseaddr = true; releaseaddr = true;
if ((hostdev->source.subsys.u.pci.backend if (backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
!= VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) { virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
configfd = qemuOpenPCIConfig(hostdev); configfd = qemuOpenPCIConfig(hostdev);
if (configfd >= 0) { if (configfd >= 0) {