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>
This commit is contained in:
parent
7bc4f3fae9
commit
a557aff0c7
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user