summaryrefslogtreecommitdiff
path: root/drivers/vfio/vfio.h
diff options
context:
space:
mode:
authorMatthew Rosato <mjrosato@linux.ibm.com>2023-02-03 16:50:26 -0500
committerAlex Williamson <alex.williamson@redhat.com>2023-02-09 11:41:25 -0700
commit2b48f52f2bff8e8926165983f3a3d7b89b33de08 (patch)
treeb4bdc8b34c8b0138d19376e5d96b9920ebe80b5f /drivers/vfio/vfio.h
parente592296cd6e15ddeebe4c8411365c550da65c8bf (diff)
downloadlwn-2b48f52f2bff8e8926165983f3a3d7b89b33de08.tar.gz
lwn-2b48f52f2bff8e8926165983f3a3d7b89b33de08.zip
vfio: fix deadlock between group lock and kvm lock
After 51cdc8bc120e, we have another deadlock scenario between the kvm->lock and the vfio group_lock with two different codepaths acquiring the locks in different order. Specifically in vfio_open_device, vfio holds the vfio group_lock when issuing device->ops->open_device but some drivers (like vfio-ap) need to acquire kvm->lock during their open_device routine; Meanwhile, kvm_vfio_release will acquire the kvm->lock first before calling vfio_file_set_kvm which will acquire the vfio group_lock. To resolve this, let's remove the need for the vfio group_lock from the kvm_vfio_release codepath. This is done by introducing a new spinlock to protect modifications to the vfio group kvm pointer, and acquiring a kvm ref from within vfio while holding this spinlock, with the reference held until the last close for the device in question. Fixes: 51cdc8bc120e ("kvm/vfio: Fix potential deadlock on vfio group_lock") Reported-by: Anthony Krowiak <akrowiak@linux.ibm.com> Suggested-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com> Tested-by: Tony Krowiak <akrowiak@linux.ibm.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Yi Liu <yi.l.liu@intel.com> Link: https://lore.kernel.org/r/20230203215027.151988-2-mjrosato@linux.ibm.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio/vfio.h')
-rw-r--r--drivers/vfio/vfio.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
index d5fa896b5a85..8ec3a5db23f5 100644
--- a/drivers/vfio/vfio.h
+++ b/drivers/vfio/vfio.h
@@ -74,6 +74,7 @@ struct vfio_group {
struct file *opened_file;
struct blocking_notifier_head notifier;
struct iommufd_ctx *iommufd;
+ spinlock_t kvm_ref_lock;
};
int vfio_device_set_group(struct vfio_device *device,
@@ -244,4 +245,18 @@ extern bool vfio_noiommu __read_mostly;
enum { vfio_noiommu = false };
#endif
+#ifdef CONFIG_HAVE_KVM
+void _vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm);
+void vfio_device_put_kvm(struct vfio_device *device);
+#else
+static inline void _vfio_device_get_kvm_safe(struct vfio_device *device,
+ struct kvm *kvm)
+{
+}
+
+static inline void vfio_device_put_kvm(struct vfio_device *device)
+{
+}
+#endif
+
#endif