aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorJean-Philippe Brucker <jean-philippe@linaro.org>2020-01-15 13:52:32 +0100
committerWill Deacon <will@kernel.org>2020-01-15 16:00:57 +0000
commita557aff0c72b62e5ca859eab376f932d24e36cea (patch)
tree8f22e2f727f184908f9e8f918d7da27accea96e8 /drivers/iommu
parentiommu/arm-smmu-v3: Prepare arm_smmu_s1_cfg for SSID support (diff)
downloadlinux-dev-a557aff0c72b62e5ca859eab376f932d24e36cea.tar.xz
linux-dev-a557aff0c72b62e5ca859eab376f932d24e36cea.zip
iommu/arm-smmu-v3: Add context descriptor tables allocators
Support for SSID will require allocating context descriptor tables. Move the context descriptor allocation to separate functions. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> Signed-off-by: Will Deacon <will@kernel.org>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/arm-smmu-v3.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 17231374eda6..3f7248d98e72 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -552,11 +552,13 @@ struct arm_smmu_ctx_desc {
struct arm_smmu_ctx_desc_cfg {
__le64 *cdtab;
dma_addr_t cdtab_dma;
+ unsigned int num_l1_ents;
};
struct arm_smmu_s1_cfg {
struct arm_smmu_ctx_desc_cfg cdcfg;
struct arm_smmu_ctx_desc cd;
+ u8 s1cdmax;
};
struct arm_smmu_s2_cfg {
@@ -1475,6 +1477,35 @@ static void arm_smmu_write_ctx_desc(struct arm_smmu_device *smmu,
cdptr[3] = cpu_to_le64(cfg->cd.mair);
}
+static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain)
+{
+ size_t l1size;
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &cfg->cdcfg;
+
+ cdcfg->num_l1_ents = 1UL << cfg->s1cdmax;
+ l1size = cdcfg->num_l1_ents * (CTXDESC_CD_DWORDS << 3);
+ cdcfg->cdtab = dmam_alloc_coherent(smmu->dev, l1size, &cdcfg->cdtab_dma,
+ GFP_KERNEL);
+ if (!cdcfg->cdtab) {
+ dev_warn(smmu->dev, "failed to allocate context descriptor\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain)
+{
+ struct arm_smmu_device *smmu = smmu_domain->smmu;
+ struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg;
+ size_t l1size = cdcfg->num_l1_ents * (CTXDESC_CD_DWORDS << 3);
+
+ dmam_free_coherent(smmu->dev, l1size, cdcfg->cdtab, cdcfg->cdtab_dma);
+ cdcfg->cdtab_dma = 0;
+ cdcfg->cdtab = NULL;
+}
+
/* Stream table manipulation functions */
static void
arm_smmu_write_strtab_l1_desc(__le64 *dst, struct arm_smmu_strtab_l1_desc *desc)
@@ -2118,11 +2149,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
if (cfg->cdcfg.cdtab) {
- dmam_free_coherent(smmu_domain->smmu->dev,
- CTXDESC_CD_DWORDS << 3,
- cfg->cdcfg.cdtab,
- cfg->cdcfg.cdtab_dma);
-
+ arm_smmu_free_cd_tables(smmu_domain);
arm_smmu_bitmap_free(smmu->asid_map, cfg->cd.asid);
}
} else {
@@ -2147,15 +2174,9 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
if (asid < 0)
return asid;
- cfg->cdcfg.cdtab = dmam_alloc_coherent(smmu->dev,
- CTXDESC_CD_DWORDS << 3,
- &cfg->cdcfg.cdtab_dma,
- GFP_KERNEL);
- if (!cfg->cdcfg.cdtab) {
- dev_warn(smmu->dev, "failed to allocate context descriptor\n");
- ret = -ENOMEM;
+ ret = arm_smmu_alloc_cd_tables(smmu_domain);
+ if (ret)
goto out_free_asid;
- }
cfg->cd.asid = (u16)asid;
cfg->cd.ttbr = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;