99#include <linux/file.h>
1010#include <linux/anon_inodes.h>
1111#include <linux/fault-inject.h>
12+ #include <linux/platform_device.h>
1213#include <uapi/linux/iommufd.h>
1314
15+ #include "../iommu-priv.h"
1416#include "io_pagetable.h"
1517#include "iommufd_private.h"
1618#include "iommufd_test.h"
1719
1820static DECLARE_FAULT_ATTR (fail_iommufd );
1921static struct dentry * dbgfs_root ;
22+ static struct platform_device * selftest_iommu_dev ;
2023
2124size_t iommufd_test_memory_limit = 65536 ;
2225
@@ -135,7 +138,7 @@ static struct iommu_domain *mock_domain_alloc(unsigned int iommu_domain_type)
135138 if (iommu_domain_type == IOMMU_DOMAIN_BLOCKED )
136139 return & mock_blocking_domain ;
137140
138- if (WARN_ON ( iommu_domain_type != IOMMU_DOMAIN_UNMANAGED ) )
141+ if (iommu_domain_type != IOMMU_DOMAIN_UNMANAGED )
139142 return NULL ;
140143
141144 mock = kzalloc (sizeof (* mock ), GFP_KERNEL );
@@ -276,12 +279,22 @@ static void mock_domain_set_plaform_dma_ops(struct device *dev)
276279 */
277280}
278281
282+ static struct iommu_device mock_iommu_device = {
283+ };
284+
285+ static struct iommu_device * mock_probe_device (struct device * dev )
286+ {
287+ return & mock_iommu_device ;
288+ }
289+
279290static const struct iommu_ops mock_ops = {
280291 .owner = THIS_MODULE ,
281292 .pgsize_bitmap = MOCK_IO_PAGE_SIZE ,
282293 .domain_alloc = mock_domain_alloc ,
283294 .capable = mock_domain_capable ,
284295 .set_platform_dma_ops = mock_domain_set_plaform_dma_ops ,
296+ .device_group = generic_device_group ,
297+ .probe_device = mock_probe_device ,
285298 .default_domain_ops =
286299 & (struct iommu_domain_ops ){
287300 .free = mock_domain_free ,
@@ -292,10 +305,6 @@ static const struct iommu_ops mock_ops = {
292305 },
293306};
294307
295- static struct iommu_device mock_iommu_device = {
296- .ops = & mock_ops ,
297- };
298-
299308static inline struct iommufd_hw_pagetable *
300309get_md_pagetable (struct iommufd_ucmd * ucmd , u32 mockpt_id ,
301310 struct mock_iommu_domain * * mock )
@@ -316,22 +325,29 @@ get_md_pagetable(struct iommufd_ucmd *ucmd, u32 mockpt_id,
316325 return hwpt ;
317326}
318327
319- static struct bus_type iommufd_mock_bus_type = {
320- .name = "iommufd_mock" ,
321- .iommu_ops = & mock_ops ,
328+ struct mock_bus_type {
329+ struct bus_type bus ;
330+ struct notifier_block nb ;
331+ };
332+
333+ static struct mock_bus_type iommufd_mock_bus_type = {
334+ .bus = {
335+ .name = "iommufd_mock" ,
336+ },
322337};
323338
339+ static atomic_t mock_dev_num ;
340+
324341static void mock_dev_release (struct device * dev )
325342{
326343 struct mock_dev * mdev = container_of (dev , struct mock_dev , dev );
327344
345+ atomic_dec (& mock_dev_num );
328346 kfree (mdev );
329347}
330348
331349static struct mock_dev * mock_dev_create (void )
332350{
333- struct iommu_group * iommu_group ;
334- struct dev_iommu * dev_iommu ;
335351 struct mock_dev * mdev ;
336352 int rc ;
337353
@@ -341,63 +357,26 @@ static struct mock_dev *mock_dev_create(void)
341357
342358 device_initialize (& mdev -> dev );
343359 mdev -> dev .release = mock_dev_release ;
344- mdev -> dev .bus = & iommufd_mock_bus_type ;
345-
346- iommu_group = iommu_group_alloc ();
347- if (IS_ERR (iommu_group )) {
348- rc = PTR_ERR (iommu_group );
349- goto err_put ;
350- }
360+ mdev -> dev .bus = & iommufd_mock_bus_type .bus ;
351361
352362 rc = dev_set_name (& mdev -> dev , "iommufd_mock%u" ,
353- iommu_group_id ( iommu_group ));
363+ atomic_inc_return ( & mock_dev_num ));
354364 if (rc )
355- goto err_group ;
356-
357- /*
358- * The iommu core has no way to associate a single device with an iommu
359- * driver (heck currently it can't even support two iommu_drivers
360- * registering). Hack it together with an open coded dev_iommu_get().
361- * Notice that the normal notifier triggered iommu release process also
362- * does not work here because this bus is not in iommu_buses.
363- */
364- mdev -> dev .iommu = kzalloc (sizeof (* dev_iommu ), GFP_KERNEL );
365- if (!mdev -> dev .iommu ) {
366- rc = - ENOMEM ;
367- goto err_group ;
368- }
369- mutex_init (& mdev -> dev .iommu -> lock );
370- mdev -> dev .iommu -> iommu_dev = & mock_iommu_device ;
365+ goto err_put ;
371366
372367 rc = device_add (& mdev -> dev );
373368 if (rc )
374- goto err_dev_iommu ;
375-
376- rc = iommu_group_add_device (iommu_group , & mdev -> dev );
377- if (rc )
378- goto err_del ;
379- iommu_group_put (iommu_group );
369+ goto err_put ;
380370 return mdev ;
381371
382- err_del :
383- device_del (& mdev -> dev );
384- err_dev_iommu :
385- kfree (mdev -> dev .iommu );
386- mdev -> dev .iommu = NULL ;
387- err_group :
388- iommu_group_put (iommu_group );
389372err_put :
390373 put_device (& mdev -> dev );
391374 return ERR_PTR (rc );
392375}
393376
394377static void mock_dev_destroy (struct mock_dev * mdev )
395378{
396- iommu_group_remove_device (& mdev -> dev );
397- device_del (& mdev -> dev );
398- kfree (mdev -> dev .iommu );
399- mdev -> dev .iommu = NULL ;
400- put_device (& mdev -> dev );
379+ device_unregister (& mdev -> dev );
401380}
402381
403382bool iommufd_selftest_is_mock_dev (struct device * dev )
@@ -444,9 +423,14 @@ static int iommufd_test_mock_domain(struct iommufd_ucmd *ucmd,
444423 cmd -> mock_domain .out_hwpt_id = pt_id ;
445424 cmd -> mock_domain .out_stdev_id = sobj -> obj .id ;
446425 cmd -> mock_domain .out_idev_id = idev_id ;
426+ rc = iommufd_ucmd_respond (ucmd , sizeof (* cmd ));
427+ if (rc )
428+ goto out_detach ;
447429 iommufd_object_finalize (ucmd -> ictx , & sobj -> obj );
448- return iommufd_ucmd_respond ( ucmd , sizeof ( * cmd )) ;
430+ return 0 ;
449431
432+ out_detach :
433+ iommufd_device_detach (idev );
450434out_unbind :
451435 iommufd_device_unbind (idev );
452436out_mdev :
@@ -1051,15 +1035,57 @@ bool iommufd_should_fail(void)
10511035 return should_fail (& fail_iommufd , 1 );
10521036}
10531037
1054- void __init iommufd_test_init (void )
1038+ int __init iommufd_test_init (void )
10551039{
1040+ struct platform_device_info pdevinfo = {
1041+ .name = "iommufd_selftest_iommu" ,
1042+ };
1043+ int rc ;
1044+
10561045 dbgfs_root =
10571046 fault_create_debugfs_attr ("fail_iommufd" , NULL , & fail_iommufd );
1058- WARN_ON (bus_register (& iommufd_mock_bus_type ));
1047+
1048+ selftest_iommu_dev = platform_device_register_full (& pdevinfo );
1049+ if (IS_ERR (selftest_iommu_dev )) {
1050+ rc = PTR_ERR (selftest_iommu_dev );
1051+ goto err_dbgfs ;
1052+ }
1053+
1054+ rc = bus_register (& iommufd_mock_bus_type .bus );
1055+ if (rc )
1056+ goto err_platform ;
1057+
1058+ rc = iommu_device_sysfs_add (& mock_iommu_device ,
1059+ & selftest_iommu_dev -> dev , NULL , "%s" ,
1060+ dev_name (& selftest_iommu_dev -> dev ));
1061+ if (rc )
1062+ goto err_bus ;
1063+
1064+ rc = iommu_device_register_bus (& mock_iommu_device , & mock_ops ,
1065+ & iommufd_mock_bus_type .bus ,
1066+ & iommufd_mock_bus_type .nb );
1067+ if (rc )
1068+ goto err_sysfs ;
1069+ return 0 ;
1070+
1071+ err_sysfs :
1072+ iommu_device_sysfs_remove (& mock_iommu_device );
1073+ err_bus :
1074+ bus_unregister (& iommufd_mock_bus_type .bus );
1075+ err_platform :
1076+ platform_device_del (selftest_iommu_dev );
1077+ err_dbgfs :
1078+ debugfs_remove_recursive (dbgfs_root );
1079+ return rc ;
10591080}
10601081
10611082void iommufd_test_exit (void )
10621083{
1084+ iommu_device_sysfs_remove (& mock_iommu_device );
1085+ iommu_device_unregister_bus (& mock_iommu_device ,
1086+ & iommufd_mock_bus_type .bus ,
1087+ & iommufd_mock_bus_type .nb );
1088+ bus_unregister (& iommufd_mock_bus_type .bus );
1089+ platform_device_del (selftest_iommu_dev );
10631090 debugfs_remove_recursive (dbgfs_root );
1064- bus_unregister (& iommufd_mock_bus_type );
10651091}
0 commit comments