From: Pavel Hrdina <phrdina@redhat.com> When fdgroup is used for iommufd we will start QEMU with -object iommufd even if the VM has no host device. When virDomainFDAssociate() is used the FD libvirt is holding is closed with connection. Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- src/qemu/qemu_command.c | 4 +++- src/qemu/qemu_hotplug.c | 4 ++-- src/qemu/qemu_process.c | 47 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 7286fd8b83..7801d99738 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5367,8 +5367,10 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd, qemuDomainObjPrivate *priv = vm->privateData; g_autoptr(virJSONValue) props = NULL; - if (!virDomainDefHasPCIHostdevWithIOMMUFD(def)) + if (!virDomainDefHasPCIHostdevWithIOMMUFD(def) && + !def->iommufd_fdgroup) { return 0; + } qemuFDPassDirectTransferCommand(priv->iommufd, cmd); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index adae94f0a2..c86ebc59d0 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1615,7 +1615,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver, if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0) goto error; - if (!priv->iommufdState) { + if (!priv->iommufdState && !vm->def->iommufd_fdgroup) { if (qemuProcessOpenIommuFd(vm) < 0) goto error; @@ -5041,7 +5041,7 @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver, } } - if (priv->iommufdState && + if (priv->iommufdState && !vm->def->iommufd_fdgroup && !virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) { qemuDomainObjEnterMonitor(vm); ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false)); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index fed6079ad2..c78fb4273c 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7743,6 +7743,44 @@ qemuProcessOpenIommuFd(virDomainObj *vm) return 0; } +/** + * qemuProcessPrepareIommuFd: + * @vm: domain object + * + * Find passed FD via virDomainFDAssociate() API for the VM. + * + * Returns: 0 on success, -1 on failure + */ +static int +qemuProcessPrepareIommuFd(virDomainObj *vm) +{ + qemuDomainObjPrivate *priv = vm->privateData; + virDomainFDTuple *fdt = virHashLookup(priv->fds, vm->def->iommufd_fdgroup); + VIR_AUTOCLOSE iommufd = -1; + + if (!fdt) { + virReportError(VIR_ERR_INVALID_ARG, + _("file descriptor group '%1$s' was not associated with the domain"), + vm->def->iommufd_fdgroup); + return -1; + } + + if (fdt->nfds != 1) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("Only one file descriptor needs to be associated with iommufd")); + return -1; + } + + iommufd = dup(fdt->fds[0]); + + if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0) + return -1; + + priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd); + + return 0; +} + /** * qemuProcessOpenVfioDeviceFd: * @hostdev: host device definition @@ -7798,9 +7836,12 @@ qemuProcessPrepareHostHostdev(virDomainObj *vm) } /* Open IOMMU FD */ - if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def) && - qemuProcessOpenIommuFd(vm) < 0) { - return -1; + if (vm->def->iommufd_fdgroup) { + if (qemuProcessPrepareIommuFd(vm) < 0) + return -1; + } else if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) { + if (qemuProcessOpenIommuFd(vm) < 0) + return -1; } return 0; -- 2.53.0