summary refs log tree commit diff stats
path: root/hw/vfio/helpers.c
diff options
context:
space:
mode:
authorCédric Le Goater <clg@redhat.com>2025-03-26 08:51:03 +0100
committerCédric Le Goater <clg@redhat.com>2025-04-25 09:01:37 +0200
commit545256134fdcac6c342f8e7f45eb591e3b12c700 (patch)
treebfda37d0d94d7295f05406d07fcdacfa37ae145e /hw/vfio/helpers.c
parentf6d7f5d02bbb57b5b469863afe89278d64598d81 (diff)
downloadfocaccia-qemu-545256134fdcac6c342f8e7f45eb591e3b12c700.tar.gz
focaccia-qemu-545256134fdcac6c342f8e7f45eb591e3b12c700.zip
vfio: Move vfio_kvm_device_add/del_fd() to helpers.c
vfio_kvm_device_add/del_fd() are low level routines. Move them with
the other helpers.

Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: John Levon <john.levon@nutanix.com>
Link: https://lore.kernel.org/qemu-devel/20250318095415.670319-18-clg@redhat.com
Link: https://lore.kernel.org/qemu-devel/20250326075122.1299361-19-clg@redhat.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
Diffstat (limited to 'hw/vfio/helpers.c')
-rw-r--r--hw/vfio/helpers.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index 1a584ba5f0..e6b75baa80 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -22,6 +22,7 @@
 #include "qemu/osdep.h"
 #include <sys/ioctl.h>
 
+#include "system/kvm.h"
 #include "hw/vfio/vfio-common.h"
 #include "hw/vfio/pci.h"
 #include "hw/hw.h"
@@ -253,6 +254,64 @@ bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info,
     return true;
 }
 
+int vfio_kvm_device_add_fd(int fd, Error **errp)
+{
+#ifdef CONFIG_KVM
+    struct kvm_device_attr attr = {
+        .group = KVM_DEV_VFIO_FILE,
+        .attr = KVM_DEV_VFIO_FILE_ADD,
+        .addr = (uint64_t)(unsigned long)&fd,
+    };
+
+    if (!kvm_enabled()) {
+        return 0;
+    }
+
+    if (vfio_kvm_device_fd < 0) {
+        struct kvm_create_device cd = {
+            .type = KVM_DEV_TYPE_VFIO,
+        };
+
+        if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) {
+            error_setg_errno(errp, errno, "Failed to create KVM VFIO device");
+            return -errno;
+        }
+
+        vfio_kvm_device_fd = cd.fd;
+    }
+
+    if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
+        error_setg_errno(errp, errno, "Failed to add fd %d to KVM VFIO device",
+                         fd);
+        return -errno;
+    }
+#endif
+    return 0;
+}
+
+int vfio_kvm_device_del_fd(int fd, Error **errp)
+{
+#ifdef CONFIG_KVM
+    struct kvm_device_attr attr = {
+        .group = KVM_DEV_VFIO_FILE,
+        .attr = KVM_DEV_VFIO_FILE_DEL,
+        .addr = (uint64_t)(unsigned long)&fd,
+    };
+
+    if (vfio_kvm_device_fd < 0) {
+        error_setg(errp, "KVM VFIO device isn't created yet");
+        return -EINVAL;
+    }
+
+    if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
+        error_setg_errno(errp, errno,
+                         "Failed to remove fd %d from KVM VFIO device", fd);
+        return -errno;
+    }
+#endif
+    return 0;
+}
+
 int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type,
                              uint32_t subtype, struct vfio_region_info **info)
 {