The ARM SMMUv3 hardwares support blocking DMA transactions by clearing the translation table entries. This implements a real blocking domain to avoid using an empty UNMANAGED domain. Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx> Tested-by: Zhangfei Gao <zhangfei.gao@xxxxxxxxxx> --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) 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 f88541be8213..5520a9607758 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -88,6 +88,8 @@ static struct arm_smmu_option_prop arm_smmu_options[] = { { 0, NULL}, }; +static void arm_smmu_detach_dev(struct arm_smmu_master *master); + static void parse_driver_options(struct arm_smmu_device *smmu) { int i = 0; @@ -2004,10 +2006,28 @@ static bool arm_smmu_capable(enum iommu_cap cap) } } +static int blocking_domain_attach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct arm_smmu_master *master = dev_iommu_priv_get(dev); + + arm_smmu_detach_dev(master); + return 0; +} + +static struct iommu_domain blocking_domain = { + .ops = &(const struct iommu_domain_ops) { + .attach_dev = blocking_domain_attach_dev + } +}; + static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) { struct arm_smmu_domain *smmu_domain; + if (type == IOMMU_DOMAIN_BLOCKED) + return &blocking_domain; + if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_DMA_FQ && -- 2.25.1