Skip to content

Commit eadd86f

Browse files
jgunthorpeAlex Williamson
authored andcommitted
vfio: Remove calls to vfio_group_add_container_user()
When the open_device() op is called the container_users is incremented and held incremented until close_device(). Thus, so long as drivers call functions within their open_device()/close_device() region they do not need to worry about the container_users. These functions can all only be called between open_device() and close_device(): vfio_pin_pages() vfio_unpin_pages() vfio_dma_rw() vfio_register_notifier() vfio_unregister_notifier() Eliminate the calls to vfio_group_add_container_user() and add vfio_assert_device_open() to detect driver mis-use. This causes the close_device() op to check device->open_count so always leave it elevated while calling the op. Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/7-v4-8045e76bf00b+13d-vfio_mdev_no_group_jgg@nvidia.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent 231657b commit eadd86f

1 file changed

Lines changed: 17 additions & 63 deletions

File tree

drivers/vfio/vfio.c

Lines changed: 17 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,12 @@ static int vfio_group_add_container_user(struct vfio_group *group)
13301330

13311331
static const struct file_operations vfio_device_fops;
13321332

1333+
/* true if the vfio_device has open_device() called but not close_device() */
1334+
static bool vfio_assert_device_open(struct vfio_device *device)
1335+
{
1336+
return !WARN_ON_ONCE(!READ_ONCE(device->open_count));
1337+
}
1338+
13331339
static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
13341340
{
13351341
struct vfio_device *device;
@@ -1544,8 +1550,10 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep)
15441550
struct vfio_device *device = filep->private_data;
15451551

15461552
mutex_lock(&device->dev_set->lock);
1547-
if (!--device->open_count && device->ops->close_device)
1553+
vfio_assert_device_open(device);
1554+
if (device->open_count == 1 && device->ops->close_device)
15481555
device->ops->close_device(device);
1556+
device->open_count--;
15491557
mutex_unlock(&device->dev_set->lock);
15501558

15511559
module_put(device->dev->driver->owner);
@@ -2112,7 +2120,8 @@ int vfio_pin_pages(struct vfio_device *device, unsigned long *user_pfn,
21122120
struct vfio_iommu_driver *driver;
21132121
int ret;
21142122

2115-
if (!user_pfn || !phys_pfn || !npage)
2123+
if (!user_pfn || !phys_pfn || !npage ||
2124+
!vfio_assert_device_open(device))
21162125
return -EINVAL;
21172126

21182127
if (npage > VFIO_PIN_PAGES_MAX_ENTRIES)
@@ -2121,10 +2130,6 @@ int vfio_pin_pages(struct vfio_device *device, unsigned long *user_pfn,
21212130
if (group->dev_counter > 1)
21222131
return -EINVAL;
21232132

2124-
ret = vfio_group_add_container_user(group);
2125-
if (ret)
2126-
return ret;
2127-
21282133
container = group->container;
21292134
driver = container->iommu_driver;
21302135
if (likely(driver && driver->ops->pin_pages))
@@ -2134,8 +2139,6 @@ int vfio_pin_pages(struct vfio_device *device, unsigned long *user_pfn,
21342139
else
21352140
ret = -ENOTTY;
21362141

2137-
vfio_group_try_dissolve_container(group);
2138-
21392142
return ret;
21402143
}
21412144
EXPORT_SYMBOL(vfio_pin_pages);
@@ -2156,16 +2159,12 @@ int vfio_unpin_pages(struct vfio_device *device, unsigned long *user_pfn,
21562159
struct vfio_iommu_driver *driver;
21572160
int ret;
21582161

2159-
if (!user_pfn || !npage)
2162+
if (!user_pfn || !npage || !vfio_assert_device_open(device))
21602163
return -EINVAL;
21612164

21622165
if (npage > VFIO_PIN_PAGES_MAX_ENTRIES)
21632166
return -E2BIG;
21642167

2165-
ret = vfio_group_add_container_user(device->group);
2166-
if (ret)
2167-
return ret;
2168-
21692168
container = device->group->container;
21702169
driver = container->iommu_driver;
21712170
if (likely(driver && driver->ops->unpin_pages))
@@ -2174,8 +2173,6 @@ int vfio_unpin_pages(struct vfio_device *device, unsigned long *user_pfn,
21742173
else
21752174
ret = -ENOTTY;
21762175

2177-
vfio_group_try_dissolve_container(device->group);
2178-
21792176
return ret;
21802177
}
21812178
EXPORT_SYMBOL(vfio_unpin_pages);
@@ -2204,13 +2201,9 @@ int vfio_dma_rw(struct vfio_device *device, dma_addr_t user_iova, void *data,
22042201
struct vfio_iommu_driver *driver;
22052202
int ret = 0;
22062203

2207-
if (!data || len <= 0)
2204+
if (!data || len <= 0 || !vfio_assert_device_open(device))
22082205
return -EINVAL;
22092206

2210-
ret = vfio_group_add_container_user(device->group);
2211-
if (ret)
2212-
return ret;
2213-
22142207
container = device->group->container;
22152208
driver = container->iommu_driver;
22162209

@@ -2219,9 +2212,6 @@ int vfio_dma_rw(struct vfio_device *device, dma_addr_t user_iova, void *data,
22192212
user_iova, data, len, write);
22202213
else
22212214
ret = -ENOTTY;
2222-
2223-
vfio_group_try_dissolve_container(device->group);
2224-
22252215
return ret;
22262216
}
22272217
EXPORT_SYMBOL(vfio_dma_rw);
@@ -2234,20 +2224,13 @@ static int vfio_register_iommu_notifier(struct vfio_group *group,
22342224
struct vfio_iommu_driver *driver;
22352225
int ret;
22362226

2237-
ret = vfio_group_add_container_user(group);
2238-
if (ret)
2239-
return -EINVAL;
2240-
22412227
container = group->container;
22422228
driver = container->iommu_driver;
22432229
if (likely(driver && driver->ops->register_notifier))
22442230
ret = driver->ops->register_notifier(container->iommu_data,
22452231
events, nb);
22462232
else
22472233
ret = -ENOTTY;
2248-
2249-
vfio_group_try_dissolve_container(group);
2250-
22512234
return ret;
22522235
}
22532236

@@ -2258,20 +2241,13 @@ static int vfio_unregister_iommu_notifier(struct vfio_group *group,
22582241
struct vfio_iommu_driver *driver;
22592242
int ret;
22602243

2261-
ret = vfio_group_add_container_user(group);
2262-
if (ret)
2263-
return -EINVAL;
2264-
22652244
container = group->container;
22662245
driver = container->iommu_driver;
22672246
if (likely(driver && driver->ops->unregister_notifier))
22682247
ret = driver->ops->unregister_notifier(container->iommu_data,
22692248
nb);
22702249
else
22712250
ret = -ENOTTY;
2272-
2273-
vfio_group_try_dissolve_container(group);
2274-
22752251
return ret;
22762252
}
22772253

@@ -2300,10 +2276,6 @@ static int vfio_register_group_notifier(struct vfio_group *group,
23002276
if (*events)
23012277
return -EINVAL;
23022278

2303-
ret = vfio_group_add_container_user(group);
2304-
if (ret)
2305-
return -EINVAL;
2306-
23072279
ret = blocking_notifier_chain_register(&group->notifier, nb);
23082280

23092281
/*
@@ -2313,25 +2285,6 @@ static int vfio_register_group_notifier(struct vfio_group *group,
23132285
if (!ret && set_kvm && group->kvm)
23142286
blocking_notifier_call_chain(&group->notifier,
23152287
VFIO_GROUP_NOTIFY_SET_KVM, group->kvm);
2316-
2317-
vfio_group_try_dissolve_container(group);
2318-
2319-
return ret;
2320-
}
2321-
2322-
static int vfio_unregister_group_notifier(struct vfio_group *group,
2323-
struct notifier_block *nb)
2324-
{
2325-
int ret;
2326-
2327-
ret = vfio_group_add_container_user(group);
2328-
if (ret)
2329-
return -EINVAL;
2330-
2331-
ret = blocking_notifier_chain_unregister(&group->notifier, nb);
2332-
2333-
vfio_group_try_dissolve_container(group);
2334-
23352288
return ret;
23362289
}
23372290

@@ -2342,7 +2295,8 @@ int vfio_register_notifier(struct vfio_device *device,
23422295
struct vfio_group *group = device->group;
23432296
int ret;
23442297

2345-
if (!nb || !events || (*events == 0))
2298+
if (!nb || !events || (*events == 0) ||
2299+
!vfio_assert_device_open(device))
23462300
return -EINVAL;
23472301

23482302
switch (type) {
@@ -2366,15 +2320,15 @@ int vfio_unregister_notifier(struct vfio_device *device,
23662320
struct vfio_group *group = device->group;
23672321
int ret;
23682322

2369-
if (!nb)
2323+
if (!nb || !vfio_assert_device_open(device))
23702324
return -EINVAL;
23712325

23722326
switch (type) {
23732327
case VFIO_IOMMU_NOTIFY:
23742328
ret = vfio_unregister_iommu_notifier(group, nb);
23752329
break;
23762330
case VFIO_GROUP_NOTIFY:
2377-
ret = vfio_unregister_group_notifier(group, nb);
2331+
ret = blocking_notifier_chain_unregister(&group->notifier, nb);
23782332
break;
23792333
default:
23802334
ret = -EINVAL;

0 commit comments

Comments
 (0)