@@ -1234,19 +1234,19 @@ static dma_addr_t arm_smmu_cd_l1_get_desc(const struct arm_smmu_cdtab_l1 *src)
1234
1234
struct arm_smmu_cd * arm_smmu_get_cd_ptr (struct arm_smmu_master * master ,
1235
1235
u32 ssid )
1236
1236
{
1237
- struct arm_smmu_l1_ctx_desc * l1_desc ;
1237
+ struct arm_smmu_cdtab_l2 * l2 ;
1238
1238
struct arm_smmu_ctx_desc_cfg * cd_table = & master -> cd_table ;
1239
1239
1240
- if (!cd_table -> cdtab )
1240
+ if (!arm_smmu_cdtab_allocated ( cd_table ) )
1241
1241
return NULL ;
1242
1242
1243
1243
if (cd_table -> s1fmt == STRTAB_STE_0_S1FMT_LINEAR )
1244
- return & (( struct arm_smmu_cd * ) cd_table -> cdtab ) [ssid ];
1244
+ return & cd_table -> linear . table [ssid ];
1245
1245
1246
- l1_desc = & cd_table -> l1_desc [arm_smmu_cdtab_l1_idx (ssid )];
1247
- if (!l1_desc -> l2ptr )
1246
+ l2 = cd_table -> l2 . l2ptrs [arm_smmu_cdtab_l1_idx (ssid )];
1247
+ if (!l2 )
1248
1248
return NULL ;
1249
- return & l1_desc -> l2ptr -> cds [arm_smmu_cdtab_l2_idx (ssid )];
1249
+ return & l2 -> cds [arm_smmu_cdtab_l2_idx (ssid )];
1250
1250
}
1251
1251
1252
1252
static struct arm_smmu_cd * arm_smmu_alloc_cd_ptr (struct arm_smmu_master * master ,
@@ -1258,30 +1258,25 @@ static struct arm_smmu_cd *arm_smmu_alloc_cd_ptr(struct arm_smmu_master *master,
1258
1258
might_sleep ();
1259
1259
iommu_group_mutex_assert (master -> dev );
1260
1260
1261
- if (!cd_table -> cdtab ) {
1261
+ if (!arm_smmu_cdtab_allocated ( cd_table ) ) {
1262
1262
if (arm_smmu_alloc_cd_tables (master ))
1263
1263
return NULL ;
1264
1264
}
1265
1265
1266
1266
if (cd_table -> s1fmt == STRTAB_STE_0_S1FMT_64K_L2 ) {
1267
1267
unsigned int idx = arm_smmu_cdtab_l1_idx (ssid );
1268
- struct arm_smmu_l1_ctx_desc * l1_desc ;
1268
+ struct arm_smmu_cdtab_l2 * * l2ptr = & cd_table -> l2 . l2ptrs [ idx ] ;
1269
1269
1270
- l1_desc = & cd_table -> l1_desc [idx ];
1271
- if (!l1_desc -> l2ptr ) {
1272
- struct arm_smmu_cdtab_l1 * dst ;
1270
+ if (!* l2ptr ) {
1273
1271
dma_addr_t l2ptr_dma ;
1274
- size_t size ;
1275
1272
1276
- size = CTXDESC_L2_ENTRIES * sizeof (struct arm_smmu_cd );
1277
- l1_desc -> l2ptr = dma_alloc_coherent (smmu -> dev , size ,
1278
- & l2ptr_dma ,
1279
- GFP_KERNEL );
1280
- if (!l1_desc -> l2ptr )
1273
+ * l2ptr = dma_alloc_coherent (smmu -> dev , sizeof (* * l2ptr ),
1274
+ & l2ptr_dma , GFP_KERNEL );
1275
+ if (!* l2ptr )
1281
1276
return NULL ;
1282
1277
1283
- dst = & (( struct arm_smmu_cdtab_l1 * ) cd_table -> cdtab ) [idx ];
1284
- arm_smmu_write_cd_l1_desc ( dst , l2ptr_dma );
1278
+ arm_smmu_write_cd_l1_desc ( & cd_table -> l2 . l1tab [idx ],
1279
+ l2ptr_dma );
1285
1280
/* An invalid L1CD can be cached */
1286
1281
arm_smmu_sync_cd (master , ssid , false);
1287
1282
}
@@ -1401,7 +1396,7 @@ void arm_smmu_clear_cd(struct arm_smmu_master *master, ioasid_t ssid)
1401
1396
struct arm_smmu_cd target = {};
1402
1397
struct arm_smmu_cd * cdptr ;
1403
1398
1404
- if (!master -> cd_table . cdtab )
1399
+ if (!arm_smmu_cdtab_allocated ( & master -> cd_table ) )
1405
1400
return ;
1406
1401
cdptr = arm_smmu_get_cd_ptr (master , ssid );
1407
1402
if (WARN_ON (!cdptr ))
@@ -1423,70 +1418,70 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
1423
1418
if (!(smmu -> features & ARM_SMMU_FEAT_2_LVL_CDTAB ) ||
1424
1419
max_contexts <= CTXDESC_L2_ENTRIES ) {
1425
1420
cd_table -> s1fmt = STRTAB_STE_0_S1FMT_LINEAR ;
1426
- cd_table -> num_l1_ents = max_contexts ;
1421
+ cd_table -> linear . num_ents = max_contexts ;
1427
1422
1428
- l1size = max_contexts * sizeof (struct arm_smmu_cd );
1423
+ l1size = max_contexts * sizeof (struct arm_smmu_cd ),
1424
+ cd_table -> linear .table = dma_alloc_coherent (smmu -> dev , l1size ,
1425
+ & cd_table -> cdtab_dma ,
1426
+ GFP_KERNEL );
1427
+ if (!cd_table -> linear .table )
1428
+ return - ENOMEM ;
1429
1429
} else {
1430
1430
cd_table -> s1fmt = STRTAB_STE_0_S1FMT_64K_L2 ;
1431
- cd_table -> num_l1_ents = DIV_ROUND_UP ( max_contexts ,
1432
- CTXDESC_L2_ENTRIES );
1431
+ cd_table -> l2 . num_l1_ents =
1432
+ DIV_ROUND_UP ( max_contexts , CTXDESC_L2_ENTRIES );
1433
1433
1434
- cd_table -> l1_desc = kcalloc (cd_table -> num_l1_ents ,
1435
- sizeof (* cd_table -> l1_desc ),
1436
- GFP_KERNEL );
1437
- if (!cd_table -> l1_desc )
1434
+ cd_table -> l2 . l2ptrs = kcalloc (cd_table -> l2 . num_l1_ents ,
1435
+ sizeof (* cd_table -> l2 . l2ptrs ),
1436
+ GFP_KERNEL );
1437
+ if (!cd_table -> l2 . l2ptrs )
1438
1438
return - ENOMEM ;
1439
1439
1440
- l1size = cd_table -> num_l1_ents * sizeof (struct arm_smmu_cdtab_l1 );
1441
- }
1442
-
1443
- cd_table -> cdtab = dma_alloc_coherent (smmu -> dev , l1size ,
1444
- & cd_table -> cdtab_dma , GFP_KERNEL );
1445
- if (!cd_table -> cdtab ) {
1446
- dev_warn (smmu -> dev , "failed to allocate context descriptor\n" );
1447
- ret = - ENOMEM ;
1448
- goto err_free_l1 ;
1440
+ l1size = cd_table -> l2 .num_l1_ents * sizeof (struct arm_smmu_cdtab_l1 );
1441
+ cd_table -> l2 .l1tab = dma_alloc_coherent (smmu -> dev , l1size ,
1442
+ & cd_table -> cdtab_dma ,
1443
+ GFP_KERNEL );
1444
+ if (!cd_table -> l2 .l2ptrs ) {
1445
+ ret = - ENOMEM ;
1446
+ goto err_free_l2ptrs ;
1447
+ }
1449
1448
}
1450
-
1451
1449
return 0 ;
1452
1450
1453
- err_free_l1 :
1454
- if (cd_table -> l1_desc ) {
1455
- kfree (cd_table -> l1_desc );
1456
- cd_table -> l1_desc = NULL ;
1457
- }
1451
+ err_free_l2ptrs :
1452
+ kfree (cd_table -> l2 .l2ptrs );
1453
+ cd_table -> l2 .l2ptrs = NULL ;
1458
1454
return ret ;
1459
1455
}
1460
1456
1461
1457
static void arm_smmu_free_cd_tables (struct arm_smmu_master * master )
1462
1458
{
1463
1459
int i ;
1464
- size_t l1size ;
1465
1460
struct arm_smmu_device * smmu = master -> smmu ;
1466
1461
struct arm_smmu_ctx_desc_cfg * cd_table = & master -> cd_table ;
1467
1462
1468
- if (cd_table -> l1_desc ) {
1469
- for (i = 0 ; i < cd_table -> num_l1_ents ; i ++ ) {
1470
- dma_addr_t dma_handle ;
1471
-
1472
- if (!cd_table -> l1_desc [i ].l2ptr )
1463
+ if (cd_table -> s1fmt != STRTAB_STE_0_S1FMT_LINEAR ) {
1464
+ for (i = 0 ; i < cd_table -> l2 .num_l1_ents ; i ++ ) {
1465
+ if (!cd_table -> l2 .l2ptrs [i ])
1473
1466
continue ;
1474
1467
1475
- dma_handle = arm_smmu_cd_l1_get_desc (& (
1476
- (struct arm_smmu_cdtab_l1 * )cd_table -> cdtab )[i ]);
1477
1468
dma_free_coherent (smmu -> dev ,
1478
- sizeof (* cd_table -> l1_desc [i ]. l2ptr ),
1479
- cd_table -> l1_desc [i ]. l2ptr ,
1480
- dma_handle );
1469
+ sizeof (* cd_table -> l2 . l2ptrs [i ]),
1470
+ cd_table -> l2 . l2ptrs [i ],
1471
+ arm_smmu_cd_l1_get_desc ( & cd_table -> l2 . l1tab [ i ]) );
1481
1472
}
1482
- kfree (cd_table -> l1_desc );
1473
+ kfree (cd_table -> l2 . l2ptrs );
1483
1474
1484
- l1size = cd_table -> num_l1_ents * sizeof (struct arm_smmu_cdtab_l1 );
1475
+ dma_free_coherent (smmu -> dev ,
1476
+ cd_table -> l2 .num_l1_ents *
1477
+ sizeof (struct arm_smmu_cdtab_l1 ),
1478
+ cd_table -> l2 .l1tab , cd_table -> cdtab_dma );
1485
1479
} else {
1486
- l1size = cd_table -> num_l1_ents * sizeof (struct arm_smmu_cd );
1480
+ dma_free_coherent (smmu -> dev ,
1481
+ cd_table -> linear .num_ents *
1482
+ sizeof (struct arm_smmu_cd ),
1483
+ cd_table -> linear .table , cd_table -> cdtab_dma );
1487
1484
}
1488
-
1489
- dma_free_coherent (smmu -> dev , l1size , cd_table -> cdtab , cd_table -> cdtab_dma );
1490
1485
}
1491
1486
1492
1487
/* Stream table manipulation functions */
@@ -3334,7 +3329,7 @@ static void arm_smmu_release_device(struct device *dev)
3334
3329
3335
3330
arm_smmu_disable_pasid (master );
3336
3331
arm_smmu_remove_master (master );
3337
- if (master -> cd_table . cdtab )
3332
+ if (arm_smmu_cdtab_allocated ( & master -> cd_table ) )
3338
3333
arm_smmu_free_cd_tables (master );
3339
3334
kfree (master );
3340
3335
}
0 commit comments