Skip to content

Commit 85196f5

Browse files
jgunthorpewilldeacon
authored andcommitted
iommu/arm-smmu-v3: Reorganize struct arm_smmu_strtab_cfg
The members here are being used for both the linear and the 2 level case, with the meaning of each item slightly different in the two cases. Split it into a clean union where both cases have their own struct with their own logical names and correct types. Adjust all the users to detect linear/2lvl and use the right sub structure and types consistently. Remove STRTAB_STE_DWORDS by changing the last places to use sizeof(struct arm_smmu_ste). 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 abb4f9d commit 85196f5

File tree

2 files changed

+50
-50
lines changed

2 files changed

+50
-50
lines changed

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

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,25 +1712,24 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
17121712
{
17131713
dma_addr_t l2ptr_dma;
17141714
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
1715-
struct arm_smmu_strtab_l1_desc *desc;
1716-
__le64 *dst;
1715+
struct arm_smmu_strtab_l2 **l2table;
17171716

1718-
desc = &cfg->l1_desc[arm_smmu_strtab_l1_idx(sid)];
1719-
if (desc->l2ptr)
1717+
l2table = &cfg->l2.l2ptrs[arm_smmu_strtab_l1_idx(sid)];
1718+
if (*l2table)
17201719
return 0;
17211720

1722-
desc->l2ptr = dmam_alloc_coherent(smmu->dev, sizeof(*desc->l2ptr),
1723-
&l2ptr_dma, GFP_KERNEL);
1724-
if (!desc->l2ptr) {
1721+
*l2table = dmam_alloc_coherent(smmu->dev, sizeof(**l2table),
1722+
&l2ptr_dma, GFP_KERNEL);
1723+
if (!*l2table) {
17251724
dev_err(smmu->dev,
17261725
"failed to allocate l2 stream table for SID %u\n",
17271726
sid);
17281727
return -ENOMEM;
17291728
}
17301729

1731-
arm_smmu_init_initial_stes(desc->l2ptr->stes, STRTAB_NUM_L2_STES);
1732-
dst = &cfg->strtab[arm_smmu_strtab_l1_idx(sid)];
1733-
arm_smmu_write_strtab_l1_desc((struct arm_smmu_strtab_l1 *)dst,
1730+
arm_smmu_init_initial_stes((*l2table)->stes,
1731+
ARRAY_SIZE((*l2table)->stes));
1732+
arm_smmu_write_strtab_l1_desc(&cfg->l2.l1tab[arm_smmu_strtab_l1_idx(sid)],
17341733
l2ptr_dma);
17351734
return 0;
17361735
}
@@ -2487,12 +2486,11 @@ arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
24872486

24882487
if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
24892488
/* Two-level walk */
2490-
return &cfg->l1_desc[arm_smmu_strtab_l1_idx(sid)]
2491-
.l2ptr->stes[arm_smmu_strtab_l2_idx(sid)];
2489+
return &cfg->l2.l2ptrs[arm_smmu_strtab_l1_idx(sid)]
2490+
->stes[arm_smmu_strtab_l2_idx(sid)];
24922491
} else {
24932492
/* Simple linear lookup */
2494-
return (struct arm_smmu_ste *)&cfg
2495-
->strtab[sid * STRTAB_STE_DWORDS];
2493+
return &cfg->linear.table[sid];
24962494
}
24972495
}
24982496

@@ -3193,8 +3191,8 @@ struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
31933191
static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
31943192
{
31953193
if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
3196-
return arm_smmu_strtab_l1_idx(sid) < smmu->strtab_cfg.num_l1_ents;
3197-
return sid < smmu->strtab_cfg.num_l1_ents;
3194+
return arm_smmu_strtab_l1_idx(sid) < smmu->strtab_cfg.l2.num_l1_ents;
3195+
return sid < smmu->strtab_cfg.linear.num_ents;
31983196
}
31993197

32003198
static int arm_smmu_init_sid_strtab(struct arm_smmu_device *smmu, u32 sid)
@@ -3629,72 +3627,69 @@ static int arm_smmu_init_queues(struct arm_smmu_device *smmu)
36293627

36303628
static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
36313629
{
3632-
void *strtab;
36333630
u64 reg;
36343631
u32 l1size;
36353632
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
36363633
unsigned int last_sid_idx =
36373634
arm_smmu_strtab_l1_idx((1 << smmu->sid_bits) - 1);
36383635

36393636
/* Calculate the L1 size, capped to the SIDSIZE. */
3640-
cfg->num_l1_ents = min(last_sid_idx + 1, STRTAB_MAX_L1_ENTRIES);
3641-
if (cfg->num_l1_ents <= last_sid_idx)
3637+
cfg->l2.num_l1_ents = min(last_sid_idx + 1, STRTAB_MAX_L1_ENTRIES);
3638+
if (cfg->l2.num_l1_ents <= last_sid_idx)
36423639
dev_warn(smmu->dev,
36433640
"2-level strtab only covers %u/%u bits of SID\n",
3644-
ilog2(cfg->num_l1_ents * STRTAB_NUM_L2_STES),
3641+
ilog2(cfg->l2.num_l1_ents * STRTAB_NUM_L2_STES),
36453642
smmu->sid_bits);
36463643

3647-
l1size = cfg->num_l1_ents * sizeof(struct arm_smmu_strtab_l1);
3648-
strtab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
3649-
GFP_KERNEL);
3650-
if (!strtab) {
3644+
l1size = cfg->l2.num_l1_ents * sizeof(struct arm_smmu_strtab_l1);
3645+
cfg->l2.l1tab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->l2.l1_dma,
3646+
GFP_KERNEL);
3647+
if (!cfg->l2.l1tab) {
36513648
dev_err(smmu->dev,
36523649
"failed to allocate l1 stream table (%u bytes)\n",
36533650
l1size);
36543651
return -ENOMEM;
36553652
}
3656-
cfg->strtab = strtab;
36573653

36583654
/* Configure strtab_base_cfg for 2 levels */
36593655
reg = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_2LVL);
36603656
reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE,
3661-
ilog2(cfg->num_l1_ents) + STRTAB_SPLIT);
3657+
ilog2(cfg->l2.num_l1_ents) + STRTAB_SPLIT);
36623658
reg |= FIELD_PREP(STRTAB_BASE_CFG_SPLIT, STRTAB_SPLIT);
36633659
cfg->strtab_base_cfg = reg;
36643660

3665-
cfg->l1_desc = devm_kcalloc(smmu->dev, cfg->num_l1_ents,
3666-
sizeof(*cfg->l1_desc), GFP_KERNEL);
3667-
if (!cfg->l1_desc)
3661+
cfg->l2.l2ptrs = devm_kcalloc(smmu->dev, cfg->l2.num_l1_ents,
3662+
sizeof(*cfg->l2.l2ptrs), GFP_KERNEL);
3663+
if (!cfg->l2.l2ptrs)
36683664
return -ENOMEM;
36693665

36703666
return 0;
36713667
}
36723668

36733669
static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
36743670
{
3675-
void *strtab;
36763671
u64 reg;
36773672
u32 size;
36783673
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
36793674

3680-
size = (1 << smmu->sid_bits) * (STRTAB_STE_DWORDS << 3);
3681-
strtab = dmam_alloc_coherent(smmu->dev, size, &cfg->strtab_dma,
3682-
GFP_KERNEL);
3683-
if (!strtab) {
3675+
size = (1 << smmu->sid_bits) * sizeof(struct arm_smmu_ste);
3676+
cfg->linear.table = dmam_alloc_coherent(smmu->dev, size,
3677+
&cfg->linear.ste_dma,
3678+
GFP_KERNEL);
3679+
if (!cfg->linear.table) {
36843680
dev_err(smmu->dev,
36853681
"failed to allocate linear stream table (%u bytes)\n",
36863682
size);
36873683
return -ENOMEM;
36883684
}
3689-
cfg->strtab = strtab;
3690-
cfg->num_l1_ents = 1 << smmu->sid_bits;
3685+
cfg->linear.num_ents = 1 << smmu->sid_bits;
36913686

36923687
/* Configure strtab_base_cfg for a linear table covering all SIDs */
36933688
reg = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_LINEAR);
36943689
reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits);
36953690
cfg->strtab_base_cfg = reg;
36963691

3697-
arm_smmu_init_initial_stes(strtab, cfg->num_l1_ents);
3692+
arm_smmu_init_initial_stes(cfg->linear.table, cfg->linear.num_ents);
36983693
return 0;
36993694
}
37003695

@@ -3703,16 +3698,17 @@ static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
37033698
u64 reg;
37043699
int ret;
37053700

3706-
if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
3701+
if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
37073702
ret = arm_smmu_init_strtab_2lvl(smmu);
3708-
else
3703+
reg = smmu->strtab_cfg.l2.l1_dma & STRTAB_BASE_ADDR_MASK;
3704+
} else {
37093705
ret = arm_smmu_init_strtab_linear(smmu);
3710-
3706+
reg = smmu->strtab_cfg.linear.ste_dma & STRTAB_BASE_ADDR_MASK;
3707+
}
37113708
if (ret)
37123709
return ret;
37133710

37143711
/* Set the strtab base address */
3715-
reg = smmu->strtab_cfg.strtab_dma & STRTAB_BASE_ADDR_MASK;
37163712
reg |= STRTAB_BASE_RA;
37173713
smmu->strtab_cfg.strtab_base = reg;
37183714

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -613,10 +613,6 @@ struct arm_smmu_priq {
613613
};
614614

615615
/* High-level stream table and context descriptor structures */
616-
struct arm_smmu_strtab_l1_desc {
617-
struct arm_smmu_strtab_l2 *l2ptr;
618-
};
619-
620616
struct arm_smmu_ctx_desc {
621617
u16 asid;
622618
};
@@ -649,11 +645,19 @@ struct arm_smmu_s2_cfg {
649645
};
650646

651647
struct arm_smmu_strtab_cfg {
652-
__le64 *strtab;
653-
dma_addr_t strtab_dma;
654-
struct arm_smmu_strtab_l1_desc *l1_desc;
655-
unsigned int num_l1_ents;
656-
648+
union {
649+
struct {
650+
struct arm_smmu_ste *table;
651+
dma_addr_t ste_dma;
652+
unsigned int num_ents;
653+
} linear;
654+
struct {
655+
struct arm_smmu_strtab_l1 *l1tab;
656+
struct arm_smmu_strtab_l2 **l2ptrs;
657+
dma_addr_t l1_dma;
658+
unsigned int num_l1_ents;
659+
} l2;
660+
};
657661
u64 strtab_base;
658662
u32 strtab_base_cfg;
659663
};

0 commit comments

Comments
 (0)