vfio: Create KVM-VFIO device

Create KVM-VFIO device and add VFIO devices to it, this can be used
to create pviommu for guests.

Signed-off-by: Mostafa Saleh <smostafa@google.com>
diff --git a/vfio/core.c b/vfio/core.c
index 074588f..c30044c 100644
--- a/vfio/core.c
+++ b/vfio/core.c
@@ -672,6 +672,37 @@
 				      NULL);
 }
 
+static int vfio_configure_kvm_device(struct kvm *kvm)
+{
+	pr_err("Create KVM-VFIO device\n");
+	struct vfio_group *group;
+	struct kvm_create_device cd = {
+		.type = KVM_DEV_TYPE_VFIO,
+	};
+
+	int ret;
+	ret = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &cd);
+	if (ret) {
+		pr_err("Failed to create kvm-vfio bridge %d\n", ret);
+		return ret;
+	}
+
+	list_for_each_entry(group, &vfio_groups, list) {
+		struct kvm_device_attr attr = {
+			.group = KVM_DEV_VFIO_GROUP,
+			.attr = KVM_DEV_VFIO_GROUP_ADD,
+			.addr = (uint64_t)(unsigned long)&group->fd,
+		};
+		ret = ioctl(cd.fd, KVM_SET_DEVICE_ATTR, &attr);
+		if (ret) {
+			pr_err("Failed to create add group to kvm-vfio device %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int vfio__init(struct kvm *kvm)
 {
 	int ret;
@@ -695,6 +726,10 @@
 	if (ret)
 		return ret;
 
+	ret = vfio_configure_kvm_device(kvm);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 dev_base_init(vfio__init);