On 2/12/26 07:25, Ani Sinha wrote:
Normally the vfio pseudo device file descriptor lives for the life of the VM.
However, when the kvm VM file descriptor changes, a new file descriptor
for the pseudo device needs to be generated against the new kvm VM descriptor.
Other existing vfio descriptors needs to be reattached to the new pseudo device
descriptor. This change performs the above steps.
This chnage is untested.
It is now.
Signed-off-by: Ani Sinha <[email protected]>
---
hw/vfio/helpers.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c
index f68f8165d0..2ff189a53b 100644
--- a/hw/vfio/helpers.c
+++ b/hw/vfio/helpers.c
@@ -116,6 +116,91 @@ bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info
*info,
* we'll re-use it should another vfio device be attached before then.
*/
int vfio_kvm_device_fd = -1;
+
+/*
+ * Confidential virtual machines:
+ * During reset of confidential vms, the kvm vm file descriptor changes.
+ * In that case, the old vfio kvm file descriptor is
+ * closed and a new descriptor is created agaist the new kvm vm file
+ * descriptor.
+ */
+
+typedef struct KVMVfioFileFd {
The KVM prefix should be reserved to the KVM subsystem. Let's use
VFIO (Yeah, it's not CalmelCase)
So, VFIODeviceFd should be correct enough for the type and
'vfio_device_fd_' prefix for the routines below?
+ int fd;
+ QLIST_ENTRY(KVMVfioFileFd) node;
+} KVMVfioFileFd;
+
+static QLIST_HEAD(, KVMVfioFileFd) kvm_vfio_file_fds =
vfio_device_fds.
+ QLIST_HEAD_INITIALIZER(kvm_vfio_file_fds);
+
+static void insert_fd_to_list(int fd)
This function name is too generic. How about vfio_device_fd_list_add()
+{
+ KVMVfioFileFd *file_fd;
+ file_fd = g_malloc0(sizeof(*file_fd));
+ file_fd->fd = fd;
+ QLIST_INSERT_HEAD(&kvm_vfio_file_fds, file_fd, node);
+ return;
Please drop the return.
+}
+
+static void remove_fd_from_list(int fd)
and vfio_device_fd_list_remove() ?
+{
+ KVMVfioFileFd *file_fd, *next;
+
+ QLIST_FOREACH_SAFE(file_fd, &kvm_vfio_file_fds, node, next) {
+ if (file_fd->fd == fd) {
+ QLIST_REMOVE(file_fd, node);
+ g_free(file_fd);
+ break;
+ }
+ }
+ return;
Please remove.
+}
+
+static int kvm_vfio_filefd_rebind(NotifierWithReturn *notifier, void *data,
vfio_device_fd_rebind() for this one and there are some more
below.
Thanks,
C.
+ Error **errp)
+{
+ KVMVfioFileFd *file_fd;
+ int ret = 0;
+ struct kvm_device_attr attr = {
+ .group = KVM_DEV_VFIO_FILE,
+ .attr = KVM_DEV_VFIO_FILE_ADD,
+ };
+ struct kvm_create_device cd = {
+ .type = KVM_DEV_TYPE_VFIO,
+ };
+
+ /* we are not interested in pre vmfd change notification */
+ if (((VmfdChangeNotifier *)data)->pre) {
+ return 0;
+ }
+
+ if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) {
+ error_setg_errno(errp, errno, "Failed to create KVM VFIO device");
+ return -errno;
+ }
+
+ if (vfio_kvm_device_fd != -1) {
+ close(vfio_kvm_device_fd);
+ }
+
+ vfio_kvm_device_fd = cd.fd;
+
+ QLIST_FOREACH(file_fd, &kvm_vfio_file_fds, node) {
+ attr.addr = (uint64_t)(unsigned long)&file_fd->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",
+ file_fd->fd);
+ ret = -errno;
+ }
+ }
+ return ret;
+}
+
+static struct NotifierWithReturn kvm_vfio_vmfd_change_notifier = {
+ .notify = kvm_vfio_filefd_rebind,
+};
+
#endif
void vfio_kvm_device_close(void)
@@ -153,6 +238,11 @@ int vfio_kvm_device_add_fd(int fd, Error **errp)
}
vfio_kvm_device_fd = cd.fd;
+ /*
+ * If the vm file descriptor changes, add a notifier so that we can
+ * re-create the vfio_kvm_device_fd.
+ */
+ kvm_vmfd_add_change_notifier(&kvm_vfio_vmfd_change_notifier);
}
if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) {
@@ -160,6 +250,8 @@ int vfio_kvm_device_add_fd(int fd, Error **errp)
fd);
return -errno;
}
+
+ insert_fd_to_list(fd);
#endif
return 0;
}
@@ -183,6 +275,8 @@ int vfio_kvm_device_del_fd(int fd, Error **errp)
"Failed to remove fd %d from KVM VFIO device", fd);
return -errno;
}
+
+ remove_fd_from_list(fd);
#endif
return 0;
}