For first host device we need to add iommufd object as well.

Signed-off-by: Pavel Hrdina <[email protected]>
---
 src/qemu/qemu_hotplug.c | 39 +++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_process.c |  4 ++--
 src/qemu/qemu_process.h |  3 +++
 3 files changed, 44 insertions(+), 2 deletions(-)

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,
-- 
2.53.0

Reply via email to