aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2015-06-30 05:02:28 -0400
committerWill Deacon <will.deacon@arm.com>2015-07-08 12:24:38 -0400
commitd2e88e7c081efb2c5a9e1adb2a065d373167af4b (patch)
tree4e329cf2ef9e7b86954b02c29d1463d0c9edbaee
parent69146e7bfc38139a134c79a4ee6607c881891786 (diff)
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: Zhen Lei <thunder.leizhen@huawei.com> Tested-by: Zhen Lei <thunder.leizhen@huawei.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--drivers/iommu/arm-smmu-v3.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 606852f18808..6b1ae4e09616 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2020,21 +2020,23 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
2020{ 2020{
2021 void *strtab; 2021 void *strtab;
2022 u64 reg; 2022 u64 reg;
2023 u32 size; 2023 u32 size, l1size;
2024 int ret; 2024 int ret;
2025 struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; 2025 struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
2026 2026
2027 /* Calculate the L1 size, capped to the SIDSIZE */ 2027 /* Calculate the L1 size, capped to the SIDSIZE */
2028 size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3); 2028 size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3);
2029 size = min(size, smmu->sid_bits - STRTAB_SPLIT); 2029 size = min(size, smmu->sid_bits - STRTAB_SPLIT);
2030 if (size + STRTAB_SPLIT < smmu->sid_bits) 2030 cfg->num_l1_ents = 1 << size;
2031
2032 size += STRTAB_SPLIT;
2033 if (size < smmu->sid_bits)
2031 dev_warn(smmu->dev, 2034 dev_warn(smmu->dev,
2032 "2-level strtab only covers %u/%u bits of SID\n", 2035 "2-level strtab only covers %u/%u bits of SID\n",
2033 size + STRTAB_SPLIT, smmu->sid_bits); 2036 size, smmu->sid_bits);
2034 2037
2035 cfg->num_l1_ents = 1 << size; 2038 l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
2036 size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3); 2039 strtab = dma_zalloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
2037 strtab = dma_zalloc_coherent(smmu->dev, size, &cfg->strtab_dma,
2038 GFP_KERNEL); 2040 GFP_KERNEL);
2039 if (!strtab) { 2041 if (!strtab) {
2040 dev_err(smmu->dev, 2042 dev_err(smmu->dev,
@@ -2055,8 +2057,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
2055 ret = arm_smmu_init_l1_strtab(smmu); 2057 ret = arm_smmu_init_l1_strtab(smmu);
2056 if (ret) 2058 if (ret)
2057 dma_free_coherent(smmu->dev, 2059 dma_free_coherent(smmu->dev,
2058 cfg->num_l1_ents * 2060 l1size,
2059 (STRTAB_L1_DESC_DWORDS << 3),
2060 strtab, 2061 strtab,
2061 cfg->strtab_dma); 2062 cfg->strtab_dma);
2062 return ret; 2063 return ret;