From: Pavel Hrdina Date: Sun, 15 Feb 2026 20:21:53 +0000 (+0100) Subject: qemu_hotplug: Add support to hotplug host device with IOMMUFD X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5d16bef1a69500791be454239e3b9ac68ec53ace;p=thirdparty%2Flibvirt.git qemu_hotplug: Add support to hotplug host device with IOMMUFD For first host device we need to add iommufd object as well. Signed-off-by: Pavel Hrdina Reviewed-by: Michal Privoznik --- diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 24fbccccf0..bede4e3ccd 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1553,13 +1553,16 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver, virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV, { .hostdev = hostdev } }; virDomainDeviceInfo *info = hostdev->info; + qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); int ret; g_autoptr(virJSONValue) devprops = NULL; + g_autoptr(virJSONValue) objprops = NULL; bool releaseaddr = false; bool teardowncgroup = false; bool teardownlabel = false; bool teardowndevice = false; bool teardownmemlock = false; + bool removeiommufd = false; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); unsigned int flags = 0; @@ -1609,11 +1612,38 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver, goto error; } + if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) { + if (qemuProcessOpenVfioDeviceFd(hostdev) < 0) + goto error; + + if (!priv->iommufdState) { + if (qemuProcessOpenIommuFd(vm) < 0) + goto error; + + if (!(objprops = qemuBuildIOMMUFDProps(priv->iommufd))) + goto error; + } + } + if (!(devprops = qemuBuildPCIHostdevDevProps(vm->def, hostdev))) goto error; qemuDomainObjEnterMonitor(vm); + if (objprops) { + if ((ret = qemuFDPassDirectTransferMonitor(priv->iommufd, priv->mon)) < 0) + goto exit_monitor; + + if ((ret = qemuMonitorAddObject(priv->mon, &objprops, NULL)) < 0) + goto exit_monitor; + + priv->iommufdState = true; + removeiommufd = true; + } + + if ((ret = qemuFDPassDirectTransferMonitor(hostdevPriv->vfioDeviceFd, priv->mon)) < 0) + goto exit_monitor; + if ((ret = qemuDomainAttachExtensionDevice(priv->mon, hostdev->info)) < 0) goto exit_monitor; @@ -1644,6 +1674,15 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver, if (teardownmemlock && qemuDomainAdjustMaxMemLock(vm) < 0) VIR_WARN("Unable to reset maximum locked memory on hotplug fail"); + if (removeiommufd) { + qemuDomainObjEnterMonitor(vm); + ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false)); + qemuDomainObjExitMonitor(vm); + } + + qemuFDPassDirectTransferMonitorRollback(hostdevPriv->vfioDeviceFd, priv->mon); + qemuFDPassDirectTransferMonitorRollback(priv->iommufd, priv->mon); + if (releaseaddr) qemuDomainReleaseDeviceAddress(vm, info); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index fc7e7bc980..371b64faac 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7685,7 +7685,7 @@ qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm, * * Returns: 0 on success, -1 on failure */ -static int +int qemuProcessOpenIommuFd(virDomainObj *vm) { qemuDomainObjPrivate *priv = vm->privateData; @@ -7709,7 +7709,7 @@ qemuProcessOpenIommuFd(virDomainObj *vm) * * Returns: 0 on success, -1 on failure */ -static int +int qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) { qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev); diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 6ba846b7b1..fccd41e1a6 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -134,6 +134,9 @@ int qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm, virDomainDeviceDef *dev) ATTRIBUTE_MOCKABLE; +int qemuProcessOpenIommuFd(virDomainObj *vm); + +int qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev); int qemuProcessPrepareHost(virQEMUDriver *driver, virDomainObj *vm,