From 5e9b5534fdf50bcfc19b0fd12d44db5c8f635675 Mon Sep 17 00:00:00 2001 Message-ID: <5e9b5534fdf50bcfc19b0fd12d44db5c8f635675.1774023916.git.phrdina@redhat.com> From: Pavel Hrdina Date: Mon, 16 Mar 2026 15:29:32 +0100 Subject: [PATCH] qemu: Implement iommufd fdgroup From: Pavel Hrdina 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 Reviewed-by: Peter Krempa (cherry picked from commit 0a83b28795f0c18592f9d842927528f0676cc56d) Resolves: https://redhat.atlassian.net/browse/VOYAGER-309 Signed-off-by: Pavel Hrdina --- 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 30bed14b0c..a76f504e6f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5361,8 +5361,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 25fe699bb3..8944062aa4 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1624,7 +1624,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; @@ -5031,7 +5031,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 5fe4a33944..2b1d47ed86 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7700,6 +7700,44 @@ qemuProcessOpenIommuFd(virDomainObj *vm) return 0; } +/** + * qemuProcessGetPassedIommuFd: + * @vm: domain object + * + * Find passed FD via virDomainFDAssociate() API for the VM. + * + * Returns: 0 on success, -1 on failure + */ +static int +qemuProcessGetPassedIommuFd(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 @@ -7755,9 +7793,12 @@ qemuProcessPrepareHostHostdev(virDomainObj *vm) } /* Open IOMMU FD */ - if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def) && - qemuProcessOpenIommuFd(vm) < 0) { - return -1; + if (vm->def->iommufd_fdgroup) { + if (qemuProcessGetPassedIommuFd(vm) < 0) + return -1; + } else if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) { + if (qemuProcessOpenIommuFd(vm) < 0) + return -1; } return 0; -- 2.53.0