diff options
| author | Steffen Eiden <seiden@linux.ibm.com> | 2026-09-28 15:07:05 +0200 |
|---|---|---|
| committer | Christian Borntraeger <borntraeger@linux.ibm.com> | 2026-10-02 10:40:00 +0200 |
| commit | 5c3ea6d3e836debc1f7f5518a5ec0c7e058fb04a (patch) | |
| tree | 0d522d481d0ab255af411d8a74bbe2613ac47f25 /virt | |
| parent | 77037cf77a3c1b575e514a483527d88c12bb682c (diff) | |
KVM/vfio: Use file-based reference counting for KVM
Replace manual module reference counting with file-based reference
counting for KVM integration. Previously, VFIO used symbol_get() to
obtain function pointers for kvm_get_kvm_safe() and kvm_put_kvm(),
then manually tracked module references through these symbols. This
approach required storing the put_kvm function pointer in each device
and carefully managing symbol references.
Pass struct file pointers instead of struct kvm pointers throughout the
VFIO-KVM interface, leveraging the kernel's existing file reference
counting via get_file()/get_file_active() and fput(). Convert the x86
page-track API and update s390 vfio to use file_to_kvm_<arch>(). This
simplifies the code.
Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Co-developed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Acked-by: Alex Williamson <alex@shazbot.org>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Acked-by: Janosch Frank <frankja@linux.ibm.com>
Acked-by: Sean Christopherson <seanjc@google.com>
[borntraeger@linux.ibm.com remove _safe from vfio_device_get_kvm_safe]
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Diffstat (limited to 'virt')
| -rw-r--r-- | virt/kvm/vfio.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c index 6cdc4e9a333a..19548a430942 100644 --- a/virt/kvm/vfio.c +++ b/virt/kvm/vfio.c @@ -35,15 +35,15 @@ struct kvm_vfio { bool noncoherent; }; -static void kvm_vfio_file_set_kvm(struct file *file, struct kvm *kvm) +static void kvm_vfio_file_set_kvm(struct file *vfio_file, struct file *kvm) { - void (*fn)(struct file *file, struct kvm *kvm); + void (*fn)(struct file *vfio_file, struct file *kvm); fn = symbol_get(vfio_file_set_kvm); if (!fn) return; - fn(file, kvm); + fn(vfio_file, kvm); symbol_put(vfio_file_set_kvm); } @@ -144,6 +144,7 @@ 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 *kvm_file __free(fput) = NULL; struct file *filp __free(fput) = NULL; filp = fget(fd); @@ -154,6 +155,10 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd) if (!kvm_vfio_file_is_valid(filp)) return -EINVAL; + kvm_file = get_file_active(&dev->kvm->file); + if (!kvm_file) + return -ENOENT; + guard(mutex)(&kv->lock); list_for_each_entry(kvf, &kv->file_list, node) { @@ -168,7 +173,7 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd) kvf->file = get_file(filp); list_add_tail(&kvf->node, &kv->file_list); - kvm_vfio_file_set_kvm(kvf->file, dev->kvm); + kvm_vfio_file_set_kvm(kvf->file, kvm_file); kvm_vfio_update_coherency(dev); return 0; |
