9
9
#include <linux/file.h>
10
10
#include <linux/anon_inodes.h>
11
11
#include <linux/fault-inject.h>
12
+ #include <linux/platform_device.h>
12
13
#include <uapi/linux/iommufd.h>
13
14
15
+ #include "../iommu-priv.h"
14
16
#include "io_pagetable.h"
15
17
#include "iommufd_private.h"
16
18
#include "iommufd_test.h"
17
19
18
20
static DECLARE_FAULT_ATTR (fail_iommufd );
19
21
static struct dentry * dbgfs_root ;
22
+ static struct platform_device * selftest_iommu_dev ;
20
23
21
24
size_t iommufd_test_memory_limit = 65536 ;
22
25
@@ -135,7 +138,7 @@ static struct iommu_domain *mock_domain_alloc(unsigned int iommu_domain_type)
135
138
if (iommu_domain_type == IOMMU_DOMAIN_BLOCKED )
136
139
return & mock_blocking_domain ;
137
140
138
- if (WARN_ON ( iommu_domain_type != IOMMU_DOMAIN_UNMANAGED ) )
141
+ if (iommu_domain_type != IOMMU_DOMAIN_UNMANAGED )
139
142
return NULL ;
140
143
141
144
mock = kzalloc (sizeof (* mock ), GFP_KERNEL );
@@ -276,12 +279,22 @@ static void mock_domain_set_plaform_dma_ops(struct device *dev)
276
279
*/
277
280
}
278
281
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
+
279
290
static const struct iommu_ops mock_ops = {
280
291
.owner = THIS_MODULE ,
281
292
.pgsize_bitmap = MOCK_IO_PAGE_SIZE ,
282
293
.domain_alloc = mock_domain_alloc ,
283
294
.capable = mock_domain_capable ,
284
295
.set_platform_dma_ops = mock_domain_set_plaform_dma_ops ,
296
+ .device_group = generic_device_group ,
297
+ .probe_device = mock_probe_device ,
285
298
.default_domain_ops =
286
299
& (struct iommu_domain_ops ){
287
300
.free = mock_domain_free ,
@@ -292,10 +305,6 @@ static const struct iommu_ops mock_ops = {
292
305
},
293
306
};
294
307
295
- static struct iommu_device mock_iommu_device = {
296
- .ops = & mock_ops ,
297
- };
298
-
299
308
static inline struct iommufd_hw_pagetable *
300
309
get_md_pagetable (struct iommufd_ucmd * ucmd , u32 mockpt_id ,
301
310
struct mock_iommu_domain * * mock )
@@ -316,22 +325,29 @@ get_md_pagetable(struct iommufd_ucmd *ucmd, u32 mockpt_id,
316
325
return hwpt ;
317
326
}
318
327
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
+ },
322
337
};
323
338
339
+ static atomic_t mock_dev_num ;
340
+
324
341
static void mock_dev_release (struct device * dev )
325
342
{
326
343
struct mock_dev * mdev = container_of (dev , struct mock_dev , dev );
327
344
345
+ atomic_dec (& mock_dev_num );
328
346
kfree (mdev );
329
347
}
330
348
331
349
static struct mock_dev * mock_dev_create (void )
332
350
{
333
- struct iommu_group * iommu_group ;
334
- struct dev_iommu * dev_iommu ;
335
351
struct mock_dev * mdev ;
336
352
int rc ;
337
353
@@ -341,63 +357,26 @@ static struct mock_dev *mock_dev_create(void)
341
357
342
358
device_initialize (& mdev -> dev );
343
359
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 ;
351
361
352
362
rc = dev_set_name (& mdev -> dev , "iommufd_mock%u" ,
353
- iommu_group_id ( iommu_group ));
363
+ atomic_inc_return ( & mock_dev_num ));
354
364
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 ;
371
366
372
367
rc = device_add (& mdev -> dev );
373
368
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 ;
380
370
return mdev ;
381
371
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 );
389
372
err_put :
390
373
put_device (& mdev -> dev );
391
374
return ERR_PTR (rc );
392
375
}
393
376
394
377
static void mock_dev_destroy (struct mock_dev * mdev )
395
378
{
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 );
401
380
}
402
381
403
382
bool iommufd_selftest_is_mock_dev (struct device * dev )
@@ -444,9 +423,14 @@ static int iommufd_test_mock_domain(struct iommufd_ucmd *ucmd,
444
423
cmd -> mock_domain .out_hwpt_id = pt_id ;
445
424
cmd -> mock_domain .out_stdev_id = sobj -> obj .id ;
446
425
cmd -> mock_domain .out_idev_id = idev_id ;
426
+ rc = iommufd_ucmd_respond (ucmd , sizeof (* cmd ));
427
+ if (rc )
428
+ goto out_detach ;
447
429
iommufd_object_finalize (ucmd -> ictx , & sobj -> obj );
448
- return iommufd_ucmd_respond ( ucmd , sizeof ( * cmd )) ;
430
+ return 0 ;
449
431
432
+ out_detach :
433
+ iommufd_device_detach (idev );
450
434
out_unbind :
451
435
iommufd_device_unbind (idev );
452
436
out_mdev :
@@ -1051,15 +1035,57 @@ bool iommufd_should_fail(void)
1051
1035
return should_fail (& fail_iommufd , 1 );
1052
1036
}
1053
1037
1054
- void __init iommufd_test_init (void )
1038
+ int __init iommufd_test_init (void )
1055
1039
{
1040
+ struct platform_device_info pdevinfo = {
1041
+ .name = "iommufd_selftest_iommu" ,
1042
+ };
1043
+ int rc ;
1044
+
1056
1045
dbgfs_root =
1057
1046
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 ;
1059
1080
}
1060
1081
1061
1082
void iommufd_test_exit (void )
1062
1083
{
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 );
1063
1090
debugfs_remove_recursive (dbgfs_root );
1064
- bus_unregister (& iommufd_mock_bus_type );
1065
1091
}
0 commit comments