Skip to content

Commit

Permalink
iommu/arm-smmu-v3: Add types for each level of the 2 level stream table
Browse files Browse the repository at this point in the history
Add types struct arm_smmu_strtab_l1 and l2 to represent the HW layout of
the descriptors, and use them in most places, following patches will get
the remaing places. The size of the l1 and l2 HW allocations are
sizeof(struct arm_smmu_strtab_l1/2).

This provides some more clarity than having raw __le64 *'s and sizes
computed via macros.

Remove STRTAB_L1_DESC_DWORDS.

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]>
  • Loading branch information
jgunthorpe authored and willdeacon committed Sep 9, 2024
1 parent ce41041 commit abb4f9d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
21 changes: 11 additions & 10 deletions drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1496,15 +1496,16 @@ static void arm_smmu_free_cd_tables(struct arm_smmu_master *master)
}

/* Stream table manipulation functions */
static void arm_smmu_write_strtab_l1_desc(__le64 *dst, dma_addr_t l2ptr_dma)
static void arm_smmu_write_strtab_l1_desc(struct arm_smmu_strtab_l1 *dst,
dma_addr_t l2ptr_dma)
{
u64 val = 0;

val |= FIELD_PREP(STRTAB_L1_DESC_SPAN, STRTAB_SPLIT + 1);
val |= l2ptr_dma & STRTAB_L1_DESC_L2PTR_MASK;

/* The HW has 64 bit atomicity with stores to the L2 STE table */
WRITE_ONCE(*dst, cpu_to_le64(val));
WRITE_ONCE(dst->l2ptr, cpu_to_le64(val));
}

struct arm_smmu_ste_writer {
Expand Down Expand Up @@ -1709,27 +1710,27 @@ static void arm_smmu_init_initial_stes(struct arm_smmu_ste *strtab,

static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
{
size_t size;
dma_addr_t l2ptr_dma;
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
struct arm_smmu_strtab_l1_desc *desc;
__le64 *dst;

desc = &cfg->l1_desc[arm_smmu_strtab_l1_idx(sid)];
if (desc->l2ptr)
return 0;

size = STRTAB_NUM_L2_STES * sizeof(struct arm_smmu_ste);
desc->l2ptr = dmam_alloc_coherent(smmu->dev, size, &l2ptr_dma,
GFP_KERNEL);
desc->l2ptr = dmam_alloc_coherent(smmu->dev, sizeof(*desc->l2ptr),
&l2ptr_dma, GFP_KERNEL);
if (!desc->l2ptr) {
dev_err(smmu->dev,
"failed to allocate l2 stream table for SID %u\n",
sid);
return -ENOMEM;
}

arm_smmu_init_initial_stes(desc->l2ptr, STRTAB_NUM_L2_STES);
arm_smmu_write_strtab_l1_desc(&cfg->strtab[arm_smmu_strtab_l1_idx(sid)],
arm_smmu_init_initial_stes(desc->l2ptr->stes, STRTAB_NUM_L2_STES);
dst = &cfg->strtab[arm_smmu_strtab_l1_idx(sid)];
arm_smmu_write_strtab_l1_desc((struct arm_smmu_strtab_l1 *)dst,
l2ptr_dma);
return 0;
}
Expand Down Expand Up @@ -2487,7 +2488,7 @@ arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
/* Two-level walk */
return &cfg->l1_desc[arm_smmu_strtab_l1_idx(sid)]
.l2ptr[arm_smmu_strtab_l2_idx(sid)];
.l2ptr->stes[arm_smmu_strtab_l2_idx(sid)];
} else {
/* Simple linear lookup */
return (struct arm_smmu_ste *)&cfg
Expand Down Expand Up @@ -3643,7 +3644,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
ilog2(cfg->num_l1_ents * STRTAB_NUM_L2_STES),
smmu->sid_bits);

l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
l1size = cfg->num_l1_ents * sizeof(struct arm_smmu_strtab_l1);
strtab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
GFP_KERNEL);
if (!strtab) {
Expand Down
10 changes: 8 additions & 2 deletions drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ struct arm_smmu_device;
*/
#define STRTAB_SPLIT 8

#define STRTAB_L1_DESC_DWORDS 1
#define STRTAB_L1_DESC_SPAN GENMASK_ULL(4, 0)
#define STRTAB_L1_DESC_L2PTR_MASK GENMASK_ULL(51, 6)

Expand All @@ -217,6 +216,13 @@ struct arm_smmu_ste {
};

#define STRTAB_NUM_L2_STES (1 << STRTAB_SPLIT)
struct arm_smmu_strtab_l2 {
struct arm_smmu_ste stes[STRTAB_NUM_L2_STES];
};

struct arm_smmu_strtab_l1 {
__le64 l2ptr;
};
#define STRTAB_MAX_L1_ENTRIES (1 << 17)

static inline u32 arm_smmu_strtab_l1_idx(u32 sid)
Expand Down Expand Up @@ -608,7 +614,7 @@ struct arm_smmu_priq {

/* High-level stream table and context descriptor structures */
struct arm_smmu_strtab_l1_desc {
struct arm_smmu_ste *l2ptr;
struct arm_smmu_strtab_l2 *l2ptr;
};

struct arm_smmu_ctx_desc {
Expand Down

0 comments on commit abb4f9d

Please sign in to comment.