Skip to content

Commit 7c567eb

Browse files
jgunthorpewilldeacon
authored andcommitted
iommu/arm-smmu-v3: Add types for each level of the CD table
As well as indexing helpers arm_smmu_cdtab_l1/2_idx(). Remove CTXDESC_L1_DESC_DWORDS and CTXDESC_CD_DWORDS replacing them all with type specific calculations. Tested-by: Nicolin Chen <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent c0a25a9 commit 7c567eb

File tree

2 files changed

+44
-24
lines changed

2 files changed

+44
-24
lines changed

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,17 +1217,18 @@ static void arm_smmu_sync_cd(struct arm_smmu_master *master,
12171217
arm_smmu_cmdq_batch_submit(smmu, &cmds);
12181218
}
12191219

1220-
static void arm_smmu_write_cd_l1_desc(__le64 *dst, dma_addr_t l2ptr_dma)
1220+
static void arm_smmu_write_cd_l1_desc(struct arm_smmu_cdtab_l1 *dst,
1221+
dma_addr_t l2ptr_dma)
12211222
{
12221223
u64 val = (l2ptr_dma & CTXDESC_L1_DESC_L2PTR_MASK) | CTXDESC_L1_DESC_V;
12231224

12241225
/* The HW has 64 bit atomicity with stores to the L2 CD table */
1225-
WRITE_ONCE(*dst, cpu_to_le64(val));
1226+
WRITE_ONCE(dst->l2ptr, cpu_to_le64(val));
12261227
}
12271228

1228-
static dma_addr_t arm_smmu_cd_l1_get_desc(const __le64 *src)
1229+
static dma_addr_t arm_smmu_cd_l1_get_desc(const struct arm_smmu_cdtab_l1 *src)
12291230
{
1230-
return le64_to_cpu(*src) & CTXDESC_L1_DESC_L2PTR_MASK;
1231+
return le64_to_cpu(src->l2ptr) & CTXDESC_L1_DESC_L2PTR_MASK;
12311232
}
12321233

12331234
struct arm_smmu_cd *arm_smmu_get_cd_ptr(struct arm_smmu_master *master,
@@ -1240,13 +1241,12 @@ struct arm_smmu_cd *arm_smmu_get_cd_ptr(struct arm_smmu_master *master,
12401241
return NULL;
12411242

12421243
if (cd_table->s1fmt == STRTAB_STE_0_S1FMT_LINEAR)
1243-
return (struct arm_smmu_cd *)(cd_table->cdtab +
1244-
ssid * CTXDESC_CD_DWORDS);
1244+
return &((struct arm_smmu_cd *)cd_table->cdtab)[ssid];
12451245

1246-
l1_desc = &cd_table->l1_desc[ssid / CTXDESC_L2_ENTRIES];
1246+
l1_desc = &cd_table->l1_desc[arm_smmu_cdtab_l1_idx(ssid)];
12471247
if (!l1_desc->l2ptr)
12481248
return NULL;
1249-
return &l1_desc->l2ptr[ssid % CTXDESC_L2_ENTRIES];
1249+
return &l1_desc->l2ptr->cds[arm_smmu_cdtab_l2_idx(ssid)];
12501250
}
12511251

12521252
static struct arm_smmu_cd *arm_smmu_alloc_cd_ptr(struct arm_smmu_master *master,
@@ -1264,11 +1264,12 @@ static struct arm_smmu_cd *arm_smmu_alloc_cd_ptr(struct arm_smmu_master *master,
12641264
}
12651265

12661266
if (cd_table->s1fmt == STRTAB_STE_0_S1FMT_64K_L2) {
1267-
unsigned int idx = ssid / CTXDESC_L2_ENTRIES;
1267+
unsigned int idx = arm_smmu_cdtab_l1_idx(ssid);
12681268
struct arm_smmu_l1_ctx_desc *l1_desc;
12691269

12701270
l1_desc = &cd_table->l1_desc[idx];
12711271
if (!l1_desc->l2ptr) {
1272+
struct arm_smmu_cdtab_l1 *dst;
12721273
dma_addr_t l2ptr_dma;
12731274
size_t size;
12741275

@@ -1279,8 +1280,8 @@ static struct arm_smmu_cd *arm_smmu_alloc_cd_ptr(struct arm_smmu_master *master,
12791280
if (!l1_desc->l2ptr)
12801281
return NULL;
12811282

1282-
arm_smmu_write_cd_l1_desc(&cd_table->cdtab[idx],
1283-
l2ptr_dma);
1283+
dst = &((struct arm_smmu_cdtab_l1 *)cd_table->cdtab)[idx];
1284+
arm_smmu_write_cd_l1_desc(dst, l2ptr_dma);
12841285
/* An invalid L1CD can be cached */
12851286
arm_smmu_sync_cd(master, ssid, false);
12861287
}
@@ -1424,7 +1425,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
14241425
cd_table->s1fmt = STRTAB_STE_0_S1FMT_LINEAR;
14251426
cd_table->num_l1_ents = max_contexts;
14261427

1427-
l1size = max_contexts * (CTXDESC_CD_DWORDS << 3);
1428+
l1size = max_contexts * sizeof(struct arm_smmu_cd);
14281429
} else {
14291430
cd_table->s1fmt = STRTAB_STE_0_S1FMT_64K_L2;
14301431
cd_table->num_l1_ents = DIV_ROUND_UP(max_contexts,
@@ -1436,7 +1437,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
14361437
if (!cd_table->l1_desc)
14371438
return -ENOMEM;
14381439

1439-
l1size = cd_table->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
1440+
l1size = cd_table->num_l1_ents * sizeof(struct arm_smmu_cdtab_l1);
14401441
}
14411442

14421443
cd_table->cdtab = dma_alloc_coherent(smmu->dev, l1size,
@@ -1460,27 +1461,29 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master)
14601461
static void arm_smmu_free_cd_tables(struct arm_smmu_master *master)
14611462
{
14621463
int i;
1463-
size_t size, l1size;
1464+
size_t l1size;
14641465
struct arm_smmu_device *smmu = master->smmu;
14651466
struct arm_smmu_ctx_desc_cfg *cd_table = &master->cd_table;
14661467

14671468
if (cd_table->l1_desc) {
1468-
size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3);
1469-
14701469
for (i = 0; i < cd_table->num_l1_ents; i++) {
1470+
dma_addr_t dma_handle;
1471+
14711472
if (!cd_table->l1_desc[i].l2ptr)
14721473
continue;
14731474

1474-
dma_free_coherent(smmu->dev, size,
1475+
dma_handle = arm_smmu_cd_l1_get_desc(&(
1476+
(struct arm_smmu_cdtab_l1 *)cd_table->cdtab)[i]);
1477+
dma_free_coherent(smmu->dev,
1478+
sizeof(*cd_table->l1_desc[i].l2ptr),
14751479
cd_table->l1_desc[i].l2ptr,
1476-
arm_smmu_cd_l1_get_desc(
1477-
&cd_table->cdtab[i]));
1480+
dma_handle);
14781481
}
14791482
kfree(cd_table->l1_desc);
14801483

1481-
l1size = cd_table->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
1484+
l1size = cd_table->num_l1_ents * sizeof(struct arm_smmu_cdtab_l1);
14821485
} else {
1483-
l1size = cd_table->num_l1_ents * (CTXDESC_CD_DWORDS << 3);
1486+
l1size = cd_table->num_l1_ents * sizeof(struct arm_smmu_cd);
14841487
}
14851488

14861489
dma_free_coherent(smmu->dev, l1size, cd_table->cdtab, cd_table->cdtab_dma);

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,6 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
301301
*/
302302
#define CTXDESC_L2_ENTRIES 1024
303303

304-
#define CTXDESC_L1_DESC_DWORDS 1
305304
#define CTXDESC_L1_DESC_V (1UL << 0)
306305
#define CTXDESC_L1_DESC_L2PTR_MASK GENMASK_ULL(51, 12)
307306

@@ -311,6 +310,24 @@ struct arm_smmu_cd {
311310
__le64 data[CTXDESC_CD_DWORDS];
312311
};
313312

313+
struct arm_smmu_cdtab_l2 {
314+
struct arm_smmu_cd cds[CTXDESC_L2_ENTRIES];
315+
};
316+
317+
struct arm_smmu_cdtab_l1 {
318+
__le64 l2ptr;
319+
};
320+
321+
static inline unsigned int arm_smmu_cdtab_l1_idx(unsigned int ssid)
322+
{
323+
return ssid / CTXDESC_L2_ENTRIES;
324+
}
325+
326+
static inline unsigned int arm_smmu_cdtab_l2_idx(unsigned int ssid)
327+
{
328+
return ssid % CTXDESC_L2_ENTRIES;
329+
}
330+
314331
#define CTXDESC_CD_0_TCR_T0SZ GENMASK_ULL(5, 0)
315332
#define CTXDESC_CD_0_TCR_TG0 GENMASK_ULL(7, 6)
316333
#define CTXDESC_CD_0_TCR_IRGN0 GENMASK_ULL(9, 8)
@@ -341,7 +358,7 @@ struct arm_smmu_cd {
341358
* When the SMMU only supports linear context descriptor tables, pick a
342359
* reasonable size limit (64kB).
343360
*/
344-
#define CTXDESC_LINEAR_CDMAX ilog2(SZ_64K / (CTXDESC_CD_DWORDS << 3))
361+
#define CTXDESC_LINEAR_CDMAX ilog2(SZ_64K / sizeof(struct arm_smmu_cd))
345362

346363
/* Command queue */
347364
#define CMDQ_ENT_SZ_SHIFT 4
@@ -618,7 +635,7 @@ struct arm_smmu_ctx_desc {
618635
};
619636

620637
struct arm_smmu_l1_ctx_desc {
621-
struct arm_smmu_cd *l2ptr;
638+
struct arm_smmu_cdtab_l2 *l2ptr;
622639
};
623640

624641
struct arm_smmu_ctx_desc_cfg {

0 commit comments

Comments
 (0)