aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vfio/vfio.c
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2013-04-25 18:12:38 -0400
committerAlex Williamson <alex.williamson@redhat.com>2013-04-25 18:12:38 -0400
commit9587f44aa69a4cfb13701b31a633852684bed701 (patch)
treeec0fa35e8156ab868ff5ca3581ec54ed1ad63f5d /drivers/vfio/vfio.c
parentaa2cba51a0a85dfbd5be58239e59bc5e8b5fb7cf (diff)
vfio: Convert container->group_lock to rwsem
All current users are writers, maintaining current mutual exclusion. This lets us add read users next. Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'drivers/vfio/vfio.c')
-rw-r--r--drivers/vfio/vfio.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 21eddd9e0f26..073788e50e4b 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -24,6 +24,7 @@
24#include <linux/list.h> 24#include <linux/list.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/rwsem.h>
27#include <linux/sched.h> 28#include <linux/sched.h>
28#include <linux/slab.h> 29#include <linux/slab.h>
29#include <linux/string.h> 30#include <linux/string.h>
@@ -57,7 +58,7 @@ struct vfio_iommu_driver {
57struct vfio_container { 58struct vfio_container {
58 struct kref kref; 59 struct kref kref;
59 struct list_head group_list; 60 struct list_head group_list;
60 struct mutex group_lock; 61 struct rw_semaphore group_lock;
61 struct vfio_iommu_driver *iommu_driver; 62 struct vfio_iommu_driver *iommu_driver;
62 void *iommu_data; 63 void *iommu_data;
63}; 64};
@@ -738,7 +739,7 @@ static long vfio_ioctl_check_extension(struct vfio_container *container,
738 return ret; 739 return ret;
739} 740}
740 741
741/* hold container->group_lock */ 742/* hold write lock on container->group_lock */
742static int __vfio_container_attach_groups(struct vfio_container *container, 743static int __vfio_container_attach_groups(struct vfio_container *container,
743 struct vfio_iommu_driver *driver, 744 struct vfio_iommu_driver *driver,
744 void *data) 745 void *data)
@@ -769,7 +770,7 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container,
769 struct vfio_iommu_driver *driver; 770 struct vfio_iommu_driver *driver;
770 long ret = -ENODEV; 771 long ret = -ENODEV;
771 772
772 mutex_lock(&container->group_lock); 773 down_write(&container->group_lock);
773 774
774 /* 775 /*
775 * The container is designed to be an unprivileged interface while 776 * The container is designed to be an unprivileged interface while
@@ -780,7 +781,7 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container,
780 * the container is deprivileged and returns to an unset state. 781 * the container is deprivileged and returns to an unset state.
781 */ 782 */
782 if (list_empty(&container->group_list) || container->iommu_driver) { 783 if (list_empty(&container->group_list) || container->iommu_driver) {
783 mutex_unlock(&container->group_lock); 784 up_write(&container->group_lock);
784 return -EINVAL; 785 return -EINVAL;
785 } 786 }
786 787
@@ -827,7 +828,7 @@ static long vfio_ioctl_set_iommu(struct vfio_container *container,
827 828
828 mutex_unlock(&vfio.iommu_drivers_lock); 829 mutex_unlock(&vfio.iommu_drivers_lock);
829skip_drivers_unlock: 830skip_drivers_unlock:
830 mutex_unlock(&container->group_lock); 831 up_write(&container->group_lock);
831 832
832 return ret; 833 return ret;
833} 834}
@@ -882,7 +883,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep)
882 return -ENOMEM; 883 return -ENOMEM;
883 884
884 INIT_LIST_HEAD(&container->group_list); 885 INIT_LIST_HEAD(&container->group_list);
885 mutex_init(&container->group_lock); 886 init_rwsem(&container->group_lock);
886 kref_init(&container->kref); 887 kref_init(&container->kref);
887 888
888 filep->private_data = container; 889 filep->private_data = container;
@@ -961,7 +962,7 @@ static void __vfio_group_unset_container(struct vfio_group *group)
961 struct vfio_container *container = group->container; 962 struct vfio_container *container = group->container;
962 struct vfio_iommu_driver *driver; 963 struct vfio_iommu_driver *driver;
963 964
964 mutex_lock(&container->group_lock); 965 down_write(&container->group_lock);
965 966
966 driver = container->iommu_driver; 967 driver = container->iommu_driver;
967 if (driver) 968 if (driver)
@@ -979,7 +980,7 @@ static void __vfio_group_unset_container(struct vfio_group *group)
979 container->iommu_data = NULL; 980 container->iommu_data = NULL;
980 } 981 }
981 982
982 mutex_unlock(&container->group_lock); 983 up_write(&container->group_lock);
983 984
984 vfio_container_put(container); 985 vfio_container_put(container);
985} 986}
@@ -1039,7 +1040,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
1039 container = f.file->private_data; 1040 container = f.file->private_data;
1040 WARN_ON(!container); /* fget ensures we don't race vfio_release */ 1041 WARN_ON(!container); /* fget ensures we don't race vfio_release */
1041 1042
1042 mutex_lock(&container->group_lock); 1043 down_write(&container->group_lock);
1043 1044
1044 driver = container->iommu_driver; 1045 driver = container->iommu_driver;
1045 if (driver) { 1046 if (driver) {
@@ -1057,7 +1058,7 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
1057 atomic_inc(&group->container_users); 1058 atomic_inc(&group->container_users);
1058 1059
1059unlock_out: 1060unlock_out:
1060 mutex_unlock(&container->group_lock); 1061 up_write(&container->group_lock);
1061 fdput(f); 1062 fdput(f);
1062 return ret; 1063 return ret;
1063} 1064}