Skip to content

Commit ce41041

Browse files
jgunthorpewilldeacon
authored andcommitted
iommu/arm-smmu-v3: Add arm_smmu_strtab_l1/2_idx()
Don't open code the calculations of the indexes for each level, provide two functions to do that math and call them in all the places. Update all the places computing indexes. Calculate the L1 table size directly based on the max required index from the cap. Remove STRTAB_L1_SZ_SHIFT in favour of STRTAB_NUM_L2_STES. Use STRTAB_NUM_L2_STES to replace remaining open coded 1 << STRTAB_SPLIT. 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 19eb465 commit ce41041

File tree

2 files changed

+32
-27
lines changed

2 files changed

+32
-27
lines changed

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

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,17 +1710,15 @@ static void arm_smmu_init_initial_stes(struct arm_smmu_ste *strtab,
17101710
static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
17111711
{
17121712
size_t size;
1713-
void *strtab;
17141713
dma_addr_t l2ptr_dma;
17151714
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
1716-
struct arm_smmu_strtab_l1_desc *desc = &cfg->l1_desc[sid >> STRTAB_SPLIT];
1715+
struct arm_smmu_strtab_l1_desc *desc;
17171716

1717+
desc = &cfg->l1_desc[arm_smmu_strtab_l1_idx(sid)];
17181718
if (desc->l2ptr)
17191719
return 0;
17201720

1721-
size = 1 << (STRTAB_SPLIT + ilog2(STRTAB_STE_DWORDS) + 3);
1722-
strtab = &cfg->strtab[(sid >> STRTAB_SPLIT) * STRTAB_L1_DESC_DWORDS];
1723-
1721+
size = STRTAB_NUM_L2_STES * sizeof(struct arm_smmu_ste);
17241722
desc->l2ptr = dmam_alloc_coherent(smmu->dev, size, &l2ptr_dma,
17251723
GFP_KERNEL);
17261724
if (!desc->l2ptr) {
@@ -1730,8 +1728,9 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
17301728
return -ENOMEM;
17311729
}
17321730

1733-
arm_smmu_init_initial_stes(desc->l2ptr, 1 << STRTAB_SPLIT);
1734-
arm_smmu_write_strtab_l1_desc(strtab, l2ptr_dma);
1731+
arm_smmu_init_initial_stes(desc->l2ptr, STRTAB_NUM_L2_STES);
1732+
arm_smmu_write_strtab_l1_desc(&cfg->strtab[arm_smmu_strtab_l1_idx(sid)],
1733+
l2ptr_dma);
17351734
return 0;
17361735
}
17371736

@@ -2486,12 +2485,9 @@ arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
24862485
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
24872486

24882487
if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
2489-
unsigned int idx1, idx2;
2490-
24912488
/* Two-level walk */
2492-
idx1 = (sid >> STRTAB_SPLIT) * STRTAB_L1_DESC_DWORDS;
2493-
idx2 = sid & ((1 << STRTAB_SPLIT) - 1);
2494-
return &cfg->l1_desc[idx1].l2ptr[idx2];
2489+
return &cfg->l1_desc[arm_smmu_strtab_l1_idx(sid)]
2490+
.l2ptr[arm_smmu_strtab_l2_idx(sid)];
24952491
} else {
24962492
/* Simple linear lookup */
24972493
return (struct arm_smmu_ste *)&cfg
@@ -3195,12 +3191,9 @@ struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
31953191

31963192
static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
31973193
{
3198-
unsigned long limit = smmu->strtab_cfg.num_l1_ents;
3199-
32003194
if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
3201-
limit *= 1UL << STRTAB_SPLIT;
3202-
3203-
return sid < limit;
3195+
return arm_smmu_strtab_l1_idx(sid) < smmu->strtab_cfg.num_l1_ents;
3196+
return sid < smmu->strtab_cfg.num_l1_ents;
32043197
}
32053198

32063199
static int arm_smmu_init_sid_strtab(struct arm_smmu_device *smmu, u32 sid)
@@ -3637,19 +3630,18 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
36373630
{
36383631
void *strtab;
36393632
u64 reg;
3640-
u32 size, l1size;
3633+
u32 l1size;
36413634
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
3635+
unsigned int last_sid_idx =
3636+
arm_smmu_strtab_l1_idx((1 << smmu->sid_bits) - 1);
36423637

36433638
/* Calculate the L1 size, capped to the SIDSIZE. */
3644-
size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3);
3645-
size = min(size, smmu->sid_bits - STRTAB_SPLIT);
3646-
cfg->num_l1_ents = 1 << size;
3647-
3648-
size += STRTAB_SPLIT;
3649-
if (size < smmu->sid_bits)
3639+
cfg->num_l1_ents = min(last_sid_idx + 1, STRTAB_MAX_L1_ENTRIES);
3640+
if (cfg->num_l1_ents <= last_sid_idx)
36503641
dev_warn(smmu->dev,
36513642
"2-level strtab only covers %u/%u bits of SID\n",
3652-
size, smmu->sid_bits);
3643+
ilog2(cfg->num_l1_ents * STRTAB_NUM_L2_STES),
3644+
smmu->sid_bits);
36533645

36543646
l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
36553647
strtab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
@@ -3664,7 +3656,8 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
36643656

36653657
/* Configure strtab_base_cfg for 2 levels */
36663658
reg = FIELD_PREP(STRTAB_BASE_CFG_FMT, STRTAB_BASE_CFG_FMT_2LVL);
3667-
reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, size);
3659+
reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE,
3660+
ilog2(cfg->num_l1_ents) + STRTAB_SPLIT);
36683661
reg |= FIELD_PREP(STRTAB_BASE_CFG_SPLIT, STRTAB_SPLIT);
36693662
cfg->strtab_base_cfg = reg;
36703663

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ struct arm_smmu_device;
204204
* 2lvl: 128k L1 entries,
205205
* 256 lazy entries per table (each table covers a PCI bus)
206206
*/
207-
#define STRTAB_L1_SZ_SHIFT 20
208207
#define STRTAB_SPLIT 8
209208

210209
#define STRTAB_L1_DESC_DWORDS 1
@@ -217,6 +216,19 @@ struct arm_smmu_ste {
217216
__le64 data[STRTAB_STE_DWORDS];
218217
};
219218

219+
#define STRTAB_NUM_L2_STES (1 << STRTAB_SPLIT)
220+
#define STRTAB_MAX_L1_ENTRIES (1 << 17)
221+
222+
static inline u32 arm_smmu_strtab_l1_idx(u32 sid)
223+
{
224+
return sid / STRTAB_NUM_L2_STES;
225+
}
226+
227+
static inline u32 arm_smmu_strtab_l2_idx(u32 sid)
228+
{
229+
return sid % STRTAB_NUM_L2_STES;
230+
}
231+
220232
#define STRTAB_STE_0_V (1UL << 0)
221233
#define STRTAB_STE_0_CFG GENMASK_ULL(3, 1)
222234
#define STRTAB_STE_0_CFG_ABORT 0

0 commit comments

Comments
 (0)