summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2017-07-07 17:37:38 -0400
committerAlex Williamson <alex.williamson@redhat.com>2017-07-07 17:37:38 -0400
commit7f56c30bd0a232822aca38d288da475613bdff9b (patch)
treede4ef02762b2c79b6801778defdea587718eeb89
parent5d6dee80a1e94cc284d03e06d930e60e8d3ecf7d (diff)
vfio: Remove unnecessary uses of vfio_container.group_lock
The original intent of vfio_container.group_lock is to protect vfio_container.group_list, however over time it's become a crutch to prevent changes in container composition any time we call into the iommu driver backend. This introduces problems when we start to have more complex interactions, for example when a user's DMA unmap request triggers a notification to an mdev vendor driver, who responds by attempting to unpin mappings within that request, re-entering the iommu backend. We incorrectly assume that the use of read-locks here allow for this nested locking behavior, but a poorly timed write-lock could in fact trigger a deadlock. The current use of group_lock seems to fall into the trap of locking code, not data. Correct that by removing uses of group_lock that are not directly related to group_list. Note that the vfio type1 iommu backend has its own mutex, vfio_iommu.lock, which it uses to protect itself for each of these interfaces anyway. The group_lock appears to be a redundancy for these interfaces and type1 even goes so far as to release its mutex to allow for exactly the re-entrant code path above. Reported-by: Chuanxiao Dong <chuanxiao.dong@intel.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Acked-by: Alexey Kardashevskiy <aik@ozlabs.ru> Cc: stable@vger.kernel.org # v4.10+
-rw-r--r--drivers/vfio/vfio.c38
1 files changed, 0 insertions, 38 deletions
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 7597a377eb4e..330d50582f40 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1175,15 +1175,11 @@ static long vfio_fops_unl_ioctl(struct file *filep,
1175 ret = vfio_ioctl_set_iommu(container, arg); 1175 ret = vfio_ioctl_set_iommu(container, arg);
1176 break; 1176 break;
1177 default: 1177 default:
1178 down_read(&container->group_lock);
1179
1180 driver = container->iommu_driver; 1178 driver = container->iommu_driver;
1181 data = container->iommu_data; 1179 data = container->iommu_data;
1182 1180
1183 if (driver) /* passthrough all unrecognized ioctls */ 1181 if (driver) /* passthrough all unrecognized ioctls */
1184 ret = driver->ops->ioctl(data, cmd, arg); 1182 ret = driver->ops->ioctl(data, cmd, arg);
1185
1186 up_read(&container->group_lock);
1187 } 1183 }
1188 1184
1189 return ret; 1185 return ret;
@@ -1237,15 +1233,11 @@ static ssize_t vfio_fops_read(struct file *filep, char __user *buf,
1237 struct vfio_iommu_driver *driver; 1233 struct vfio_iommu_driver *driver;
1238 ssize_t ret = -EINVAL; 1234 ssize_t ret = -EINVAL;
1239 1235
1240 down_read(&container->group_lock);
1241
1242 driver = container->iommu_driver; 1236 driver = container->iommu_driver;
1243 if (likely(driver && driver->ops->read)) 1237 if (likely(driver && driver->ops->read))
1244 ret = driver->ops->read(container->iommu_data, 1238 ret = driver->ops->read(container->iommu_data,
1245 buf, count, ppos); 1239 buf, count, ppos);
1246 1240
1247 up_read(&container->group_lock);
1248
1249 return ret; 1241 return ret;
1250} 1242}
1251 1243
@@ -1256,15 +1248,11 @@ static ssize_t vfio_fops_write(struct file *filep, const char __user *buf,
1256 struct vfio_iommu_driver *driver; 1248 struct vfio_iommu_driver *driver;
1257 ssize_t ret = -EINVAL; 1249 ssize_t ret = -EINVAL;
1258 1250
1259 down_read(&container->group_lock);
1260
1261 driver = container->iommu_driver; 1251 driver = container->iommu_driver;
1262 if (likely(driver && driver->ops->write)) 1252 if (likely(driver && driver->ops->write))
1263 ret = driver->ops->write(container->iommu_data, 1253 ret = driver->ops->write(container->iommu_data,
1264 buf, count, ppos); 1254 buf, count, ppos);
1265 1255
1266 up_read(&container->group_lock);
1267
1268 return ret; 1256 return ret;
1269} 1257}
1270 1258
@@ -1274,14 +1262,10 @@ static int vfio_fops_mmap(struct file *filep, struct vm_area_struct *vma)
1274 struct vfio_iommu_driver *driver; 1262 struct vfio_iommu_driver *driver;
1275 int ret = -EINVAL; 1263 int ret = -EINVAL;
1276 1264
1277 down_read(&container->group_lock);
1278
1279 driver = container->iommu_driver; 1265 driver = container->iommu_driver;
1280 if (likely(driver && driver->ops->mmap)) 1266 if (likely(driver && driver->ops->mmap))
1281 ret = driver->ops->mmap(container->iommu_data, vma); 1267 ret = driver->ops->mmap(container->iommu_data, vma);
1282 1268
1283 up_read(&container->group_lock);
1284
1285 return ret; 1269 return ret;
1286} 1270}
1287 1271
@@ -1993,8 +1977,6 @@ int vfio_pin_pages(struct device *dev, unsigned long *user_pfn, int npage,
1993 goto err_pin_pages; 1977 goto err_pin_pages;
1994 1978
1995 container = group->container; 1979 container = group->container;
1996 down_read(&container->group_lock);
1997
1998 driver = container->iommu_driver; 1980 driver = container->iommu_driver;
1999 if (likely(driver && driver->ops->pin_pages)) 1981 if (likely(driver && driver->ops->pin_pages))
2000 ret = driver->ops->pin_pages(container->iommu_data, user_pfn, 1982 ret = driver->ops->pin_pages(container->iommu_data, user_pfn,
@@ -2002,7 +1984,6 @@ int vfio_pin_pages(struct device *dev, unsigned long *user_pfn, int npage,
2002 else 1984 else
2003 ret = -ENOTTY; 1985 ret = -ENOTTY;
2004 1986
2005 up_read(&container->group_lock);
2006 vfio_group_try_dissolve_container(group); 1987 vfio_group_try_dissolve_container(group);
2007 1988
2008err_pin_pages: 1989err_pin_pages:
@@ -2042,8 +2023,6 @@ int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn, int npage)
2042 goto err_unpin_pages; 2023 goto err_unpin_pages;
2043 2024
2044 container = group->container; 2025 container = group->container;
2045 down_read(&container->group_lock);
2046
2047 driver = container->iommu_driver; 2026 driver = container->iommu_driver;
2048 if (likely(driver && driver->ops->unpin_pages)) 2027 if (likely(driver && driver->ops->unpin_pages))
2049 ret = driver->ops->unpin_pages(container->iommu_data, user_pfn, 2028 ret = driver->ops->unpin_pages(container->iommu_data, user_pfn,
@@ -2051,7 +2030,6 @@ int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn, int npage)
2051 else 2030 else
2052 ret = -ENOTTY; 2031 ret = -ENOTTY;
2053 2032
2054 up_read(&container->group_lock);
2055 vfio_group_try_dissolve_container(group); 2033 vfio_group_try_dissolve_container(group);
2056 2034
2057err_unpin_pages: 2035err_unpin_pages:
@@ -2073,8 +2051,6 @@ static int vfio_register_iommu_notifier(struct vfio_group *group,
2073 return -EINVAL; 2051 return -EINVAL;
2074 2052
2075 container = group->container; 2053 container = group->container;
2076 down_read(&container->group_lock);
2077
2078 driver = container->iommu_driver; 2054 driver = container->iommu_driver;
2079 if (likely(driver && driver->ops->register_notifier)) 2055 if (likely(driver && driver->ops->register_notifier))
2080 ret = driver->ops->register_notifier(container->iommu_data, 2056 ret = driver->ops->register_notifier(container->iommu_data,
@@ -2082,7 +2058,6 @@ static int vfio_register_iommu_notifier(struct vfio_group *group,
2082 else 2058 else
2083 ret = -ENOTTY; 2059 ret = -ENOTTY;
2084 2060
2085 up_read(&container->group_lock);
2086 vfio_group_try_dissolve_container(group); 2061 vfio_group_try_dissolve_container(group);
2087 2062
2088 return ret; 2063 return ret;
@@ -2100,8 +2075,6 @@ static int vfio_unregister_iommu_notifier(struct vfio_group *group,
2100 return -EINVAL; 2075 return -EINVAL;
2101 2076
2102 container = group->container; 2077 container = group->container;
2103 down_read(&container->group_lock);
2104
2105 driver = container->iommu_driver; 2078 driver = container->iommu_driver;
2106 if (likely(driver && driver->ops->unregister_notifier)) 2079 if (likely(driver && driver->ops->unregister_notifier))
2107 ret = driver->ops->unregister_notifier(container->iommu_data, 2080 ret = driver->ops->unregister_notifier(container->iommu_data,
@@ -2109,7 +2082,6 @@ static int vfio_unregister_iommu_notifier(struct vfio_group *group,
2109 else 2082 else
2110 ret = -ENOTTY; 2083 ret = -ENOTTY;
2111 2084
2112 up_read(&container->group_lock);
2113 vfio_group_try_dissolve_container(group); 2085 vfio_group_try_dissolve_container(group);
2114 2086
2115 return ret; 2087 return ret;
@@ -2127,7 +2099,6 @@ static int vfio_register_group_notifier(struct vfio_group *group,
2127 unsigned long *events, 2099 unsigned long *events,
2128 struct notifier_block *nb) 2100 struct notifier_block *nb)
2129{ 2101{
2130 struct vfio_container *container;
2131 int ret; 2102 int ret;
2132 bool set_kvm = false; 2103 bool set_kvm = false;
2133 2104
@@ -2145,9 +2116,6 @@ static int vfio_register_group_notifier(struct vfio_group *group,
2145 if (ret) 2116 if (ret)
2146 return -EINVAL; 2117 return -EINVAL;
2147 2118
2148 container = group->container;
2149 down_read(&container->group_lock);
2150
2151 ret = blocking_notifier_chain_register(&group->notifier, nb); 2119 ret = blocking_notifier_chain_register(&group->notifier, nb);
2152 2120
2153 /* 2121 /*
@@ -2158,7 +2126,6 @@ static int vfio_register_group_notifier(struct vfio_group *group,
2158 blocking_notifier_call_chain(&group->notifier, 2126 blocking_notifier_call_chain(&group->notifier,
2159 VFIO_GROUP_NOTIFY_SET_KVM, group->kvm); 2127 VFIO_GROUP_NOTIFY_SET_KVM, group->kvm);
2160 2128
2161 up_read(&container->group_lock);
2162 vfio_group_try_dissolve_container(group); 2129 vfio_group_try_dissolve_container(group);
2163 2130
2164 return ret; 2131 return ret;
@@ -2167,19 +2134,14 @@ static int vfio_register_group_notifier(struct vfio_group *group,
2167static int vfio_unregister_group_notifier(struct vfio_group *group, 2134static int vfio_unregister_group_notifier(struct vfio_group *group,
2168 struct notifier_block *nb) 2135 struct notifier_block *nb)
2169{ 2136{
2170 struct vfio_container *container;
2171 int ret; 2137 int ret;
2172 2138
2173 ret = vfio_group_add_container_user(group); 2139 ret = vfio_group_add_container_user(group);
2174 if (ret) 2140 if (ret)
2175 return -EINVAL; 2141 return -EINVAL;
2176 2142
2177 container = group->container;
2178 down_read(&container->group_lock);
2179
2180 ret = blocking_notifier_chain_unregister(&group->notifier, nb); 2143 ret = blocking_notifier_chain_unregister(&group->notifier, nb);
2181 2144
2182 up_read(&container->group_lock);
2183 vfio_group_try_dissolve_container(group); 2145 vfio_group_try_dissolve_container(group);
2184 2146
2185 return ret; 2147 return ret;