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 <anisinha@redhat.com>
> ---
> 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;
> }