diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2026-06-12 10:14:42 +0200 |
|---|---|---|
| committer | Paolo Bonzini <pbonzini@redhat.com> | 2026-06-12 10:14:42 +0200 |
| commit | 3ef8a08e22cbc14f979a1d00602358ad27927142 (patch) | |
| tree | c099825fad2a92e24389ad6a06251f77ae788b5d /virt | |
| parent | b39c6bd6fd4dc05ce0608b5059f840eeec994e94 (diff) | |
| parent | 156615264fd3430e7f90b36f46076b2f6ec4a24a (diff) | |
| download | linux-next-3ef8a08e22cbc14f979a1d00602358ad27927142.tar.gz linux-next-3ef8a08e22cbc14f979a1d00602358ad27927142.zip | |
Merge tag 'kvm-x86-vfio-7.2' of https://github.com/kvm-x86/linux into HEAD
KVM VFIO changes for 7.2
Use guard() to cleanup up various KVM+VFIO flows.
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/vfio.c | 98 |
1 files changed, 35 insertions, 63 deletions
diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c index 9f9acb66cc1e..6cdc4e9a333a 100644 --- a/virt/kvm/vfio.c +++ b/virt/kvm/vfio.c @@ -144,33 +144,26 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd) { struct kvm_vfio *kv = dev->private; struct kvm_vfio_file *kvf; - struct file *filp; - int ret = 0; + struct file *filp __free(fput) = NULL; filp = fget(fd); if (!filp) return -EBADF; /* Ensure the FD is a vfio FD. */ - if (!kvm_vfio_file_is_valid(filp)) { - ret = -EINVAL; - goto out_fput; - } + if (!kvm_vfio_file_is_valid(filp)) + return -EINVAL; - mutex_lock(&kv->lock); + guard(mutex)(&kv->lock); list_for_each_entry(kvf, &kv->file_list, node) { - if (kvf->file == filp) { - ret = -EEXIST; - goto out_unlock; - } + if (kvf->file == filp) + return -EEXIST; } kvf = kzalloc_obj(*kvf, GFP_KERNEL_ACCOUNT); - if (!kvf) { - ret = -ENOMEM; - goto out_unlock; - } + if (!kvf) + return -ENOMEM; kvf->file = get_file(filp); list_add_tail(&kvf->node, &kv->file_list); @@ -178,11 +171,18 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd) kvm_vfio_file_set_kvm(kvf->file, dev->kvm); kvm_vfio_update_coherency(dev); -out_unlock: - mutex_unlock(&kv->lock); -out_fput: - fput(filp); - return ret; + return 0; +} + +static void kvm_vfio_file_free(struct kvm_device *dev, struct kvm_vfio_file *kvf) +{ +#ifdef CONFIG_SPAPR_TCE_IOMMU + kvm_spapr_tce_release_vfio_group(dev->kvm, kvf); +#endif + kvm_vfio_file_set_kvm(kvf->file, NULL); + fput(kvf->file); + list_del(&kvf->node); + kfree(kvf); } static int kvm_vfio_file_del(struct kvm_device *dev, unsigned int fd) @@ -190,34 +190,21 @@ static int kvm_vfio_file_del(struct kvm_device *dev, unsigned int fd) struct kvm_vfio *kv = dev->private; struct kvm_vfio_file *kvf; CLASS(fd, f)(fd); - int ret; if (fd_empty(f)) return -EBADF; - ret = -ENOENT; - - mutex_lock(&kv->lock); + guard(mutex)(&kv->lock); list_for_each_entry(kvf, &kv->file_list, node) { - if (kvf->file != fd_file(f)) - continue; - - list_del(&kvf->node); -#ifdef CONFIG_SPAPR_TCE_IOMMU - kvm_spapr_tce_release_vfio_group(dev->kvm, kvf); -#endif - kvm_vfio_file_set_kvm(kvf->file, NULL); - fput(kvf->file); - kfree(kvf); - ret = 0; - break; + if (kvf->file == fd_file(f)) { + kvm_vfio_file_free(dev, kvf); + kvm_vfio_update_coherency(dev); + return 0; + } } - kvm_vfio_update_coherency(dev); - - mutex_unlock(&kv->lock); - return ret; + return -ENOENT; } #ifdef CONFIG_SPAPR_TCE_IOMMU @@ -227,7 +214,6 @@ static int kvm_vfio_file_set_spapr_tce(struct kvm_device *dev, struct kvm_vfio_spapr_tce param; struct kvm_vfio *kv = dev->private; struct kvm_vfio_file *kvf; - int ret; if (copy_from_user(¶m, arg, sizeof(struct kvm_vfio_spapr_tce))) return -EFAULT; @@ -236,9 +222,7 @@ static int kvm_vfio_file_set_spapr_tce(struct kvm_device *dev, if (fd_empty(f)) return -EBADF; - ret = -ENOENT; - - mutex_lock(&kv->lock); + guard(mutex)(&kv->lock); list_for_each_entry(kvf, &kv->file_list, node) { if (kvf->file != fd_file(f)) @@ -246,20 +230,15 @@ static int kvm_vfio_file_set_spapr_tce(struct kvm_device *dev, if (!kvf->iommu_group) { kvf->iommu_group = kvm_vfio_file_iommu_group(kvf->file); - if (WARN_ON_ONCE(!kvf->iommu_group)) { - ret = -EIO; - goto err_fdput; - } + if (WARN_ON_ONCE(!kvf->iommu_group)) + return -EIO; } - ret = kvm_spapr_tce_attach_iommu_group(dev->kvm, param.tablefd, - kvf->iommu_group); - break; + return kvm_spapr_tce_attach_iommu_group(dev->kvm, param.tablefd, + kvf->iommu_group); } -err_fdput: - mutex_unlock(&kv->lock); - return ret; + return -ENOENT; } #endif @@ -326,15 +305,8 @@ static void kvm_vfio_release(struct kvm_device *dev) struct kvm_vfio *kv = dev->private; struct kvm_vfio_file *kvf, *tmp; - list_for_each_entry_safe(kvf, tmp, &kv->file_list, node) { -#ifdef CONFIG_SPAPR_TCE_IOMMU - kvm_spapr_tce_release_vfio_group(dev->kvm, kvf); -#endif - kvm_vfio_file_set_kvm(kvf->file, NULL); - fput(kvf->file); - list_del(&kvf->node); - kfree(kvf); - } + list_for_each_entry_safe(kvf, tmp, &kv->file_list, node) + kvm_vfio_file_free(dev, kvf); kvm_vfio_update_coherency(dev); |
