Commit d2e88e7c authored by Will Deacon's avatar Will Deacon

iommu/arm-smmu: Fix LOG2SIZE setting for 2-level stream tables

STRTAB_BASE_CFG.LOG2SIZE should be set to log2(entries), where entries
is the *total* number of entries in the stream table, not just the first
level.

This patch fixes the register setting, which was previously being set to
the size of the l1 thanks to a multi-use "size" variable.
Reported-by: default avatarZhen Lei <thunder.leizhen@huawei.com>
Tested-by: default avatarZhen Lei <thunder.leizhen@huawei.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 69146e7b
...@@ -2020,21 +2020,23 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) ...@@ -2020,21 +2020,23 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
{ {
void *strtab; void *strtab;
u64 reg; u64 reg;
u32 size; u32 size, l1size;
int ret; int ret;
struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
/* Calculate the L1 size, capped to the SIDSIZE */ /* Calculate the L1 size, capped to the SIDSIZE */
size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3); size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3);
size = min(size, smmu->sid_bits - STRTAB_SPLIT); size = min(size, smmu->sid_bits - STRTAB_SPLIT);
if (size + STRTAB_SPLIT < smmu->sid_bits) cfg->num_l1_ents = 1 << size;
size += STRTAB_SPLIT;
if (size < smmu->sid_bits)
dev_warn(smmu->dev, dev_warn(smmu->dev,
"2-level strtab only covers %u/%u bits of SID\n", "2-level strtab only covers %u/%u bits of SID\n",
size + STRTAB_SPLIT, smmu->sid_bits); size, smmu->sid_bits);
cfg->num_l1_ents = 1 << size; l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3); strtab = dma_zalloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
strtab = dma_zalloc_coherent(smmu->dev, size, &cfg->strtab_dma,
GFP_KERNEL); GFP_KERNEL);
if (!strtab) { if (!strtab) {
dev_err(smmu->dev, dev_err(smmu->dev,
...@@ -2055,8 +2057,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) ...@@ -2055,8 +2057,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
ret = arm_smmu_init_l1_strtab(smmu); ret = arm_smmu_init_l1_strtab(smmu);
if (ret) if (ret)
dma_free_coherent(smmu->dev, dma_free_coherent(smmu->dev,
cfg->num_l1_ents * l1size,
(STRTAB_L1_DESC_DWORDS << 3),
strtab, strtab,
cfg->strtab_dma); cfg->strtab_dma);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment