@@ -1330,6 +1330,12 @@ static int vfio_group_add_container_user(struct vfio_group *group)
13301330
13311331static 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+
13331339static 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}
21412144EXPORT_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}
21812178EXPORT_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}
22272217EXPORT_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