In preparation for vSVA, let's accept userspace provided configs with more than one CD. We check the max CD against the host iommu capability and also the format (linear versus 2 level). Signed-off-by: Eric Auger <eric.auger@xxxxxxxxxx> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@xxxxxxxxxx> --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 31a2500bde32..6549c3ee6af6 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2901,11 +2901,12 @@ static int arm_smmu_attach_pasid_table(struct iommu_domain *domain, if (smmu_domain->s1_cfg) goto out; - /* - * we currently support a single CD so s1fmt and s1dss - * fields are also ignored - */ - if (cfg->pasid_bits) + list_for_each_entry(master, &smmu_domain->devices, domain_head) { + if (cfg->pasid_bits > master->ssid_bits) + goto out; + } + if (cfg->vendor_data.smmuv3.s1fmt == STRTAB_STE_0_S1FMT_64K_L2 && + !(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB)) goto out; smmu_domain->s1_cfg = kzalloc(sizeof(*smmu_domain->s1_cfg), @@ -2916,6 +2917,8 @@ static int arm_smmu_attach_pasid_table(struct iommu_domain *domain, } smmu_domain->s1_cfg->cdcfg.cdtab_dma = cfg->base_ptr; + smmu_domain->s1_cfg->s1cdmax = cfg->pasid_bits; + smmu_domain->s1_cfg->s1fmt = cfg->vendor_data.smmuv3.s1fmt; smmu_domain->abort = false; break; default: -- 2.21.3