lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <8a0fc6cf-f46e-f17e-2b76-099ada1683c3@arm.com>
Date:   Mon, 16 May 2022 12:22:08 +0100
From:   Robin Murphy <robin.murphy@....com>
To:     Lu Baolu <baolu.lu@...ux.intel.com>,
        Joerg Roedel <joro@...tes.org>,
        Jason Gunthorpe <jgg@...dia.com>,
        Christoph Hellwig <hch@...radead.org>,
        Kevin Tian <kevin.tian@...el.com>,
        Ashok Raj <ashok.raj@...el.com>, Will Deacon <will@...nel.org>,
        Jean-Philippe Brucker <jean-philippe@...aro.com>
Cc:     Eric Auger <eric.auger@...hat.com>, Liu Yi L <yi.l.liu@...el.com>,
        Jacob jun Pan <jacob.jun.pan@...el.com>,
        iommu@...ts.linux-foundation.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2/5] iommu: Add blocking_domain_ops field in iommu_ops

On 2022-05-16 02:57, Lu Baolu wrote:
> Each IOMMU driver must provide a blocking domain ops. If the hardware
> supports detaching domain from device, setting blocking domain equals
> detaching the existing domain from the deivce. Otherwise, an UNMANAGED
> domain without any mapping will be used instead.

Unfortunately that's backwards - most of the implementations of 
.detach_dev are disabling translation entirely, meaning the device ends 
up effectively in passthrough rather than blocked. Conversely, at least 
arm-smmu and arm-smmu-v3 could implement IOMMU_DOMAIN_BLOCKED properly 
with fault-type S2CRs and STEs respectively, it just needs a bit of 
wiring up.

Thanks,
Robin.

> Signed-off-by: Lu Baolu <baolu.lu@...ux.intel.com>
> ---
>   include/linux/iommu.h                       |  7 +++++++
>   drivers/iommu/amd/iommu.c                   | 12 ++++++++++++
>   drivers/iommu/apple-dart.c                  | 12 ++++++++++++
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  3 +++
>   drivers/iommu/arm/arm-smmu/arm-smmu.c       |  3 +++
>   drivers/iommu/arm/arm-smmu/qcom_iommu.c     | 12 ++++++++++++
>   drivers/iommu/exynos-iommu.c                | 12 ++++++++++++
>   drivers/iommu/fsl_pamu_domain.c             | 12 ++++++++++++
>   drivers/iommu/intel/iommu.c                 | 12 ++++++++++++
>   drivers/iommu/ipmmu-vmsa.c                  | 12 ++++++++++++
>   drivers/iommu/msm_iommu.c                   | 12 ++++++++++++
>   drivers/iommu/mtk_iommu.c                   | 12 ++++++++++++
>   drivers/iommu/mtk_iommu_v1.c                | 12 ++++++++++++
>   drivers/iommu/omap-iommu.c                  | 12 ++++++++++++
>   drivers/iommu/rockchip-iommu.c              | 12 ++++++++++++
>   drivers/iommu/s390-iommu.c                  | 12 ++++++++++++
>   drivers/iommu/sprd-iommu.c                  | 11 +++++++++++
>   drivers/iommu/sun50i-iommu.c                | 12 ++++++++++++
>   drivers/iommu/tegra-gart.c                  | 12 ++++++++++++
>   drivers/iommu/tegra-smmu.c                  | 12 ++++++++++++
>   drivers/iommu/virtio-iommu.c                |  3 +++
>   21 files changed, 219 insertions(+)
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 572399ac1d83..5e228aad0ef6 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -216,6 +216,7 @@ struct iommu_iotlb_gather {
>    *		- IOMMU_DOMAIN_DMA: must use a dma domain
>    *		- 0: use the default setting
>    * @default_domain_ops: the default ops for domains
> + * @blocking_domain_ops: the blocking ops for domains
>    * @pgsize_bitmap: bitmap of all possible supported page sizes
>    * @owner: Driver module providing these ops
>    */
> @@ -255,6 +256,7 @@ struct iommu_ops {
>   	int (*def_domain_type)(struct device *dev);
>   
>   	const struct iommu_domain_ops *default_domain_ops;
> +	const struct iommu_domain_ops *blocking_domain_ops;
>   	unsigned long pgsize_bitmap;
>   	struct module *owner;
>   };
> @@ -279,6 +281,9 @@ struct iommu_ops {
>    * @enable_nesting: Enable nesting
>    * @set_pgtable_quirks: Set io page table quirks (IO_PGTABLE_QUIRK_*)
>    * @free: Release the domain after use.
> + * @blocking_domain_detach: iommu hardware support detaching a domain from
> + *		a device, hence setting blocking domain to a device equals to
> + *		detach the existing domain from it.
>    */
>   struct iommu_domain_ops {
>   	int (*set_dev)(struct iommu_domain *domain, struct device *dev);
> @@ -310,6 +315,8 @@ struct iommu_domain_ops {
>   				  unsigned long quirks);
>   
>   	void (*free)(struct iommu_domain *domain);
> +
> +	unsigned int blocking_domain_detach:1;
>   };
>   
>   /**
> diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
> index 01b8668ef46d..c66713439824 100644
> --- a/drivers/iommu/amd/iommu.c
> +++ b/drivers/iommu/amd/iommu.c
> @@ -2272,6 +2272,14 @@ static bool amd_iommu_enforce_cache_coherency(struct iommu_domain *domain)
>   	return true;
>   }
>   
> +static int amd_blocking_domain_set_dev(struct iommu_domain *domain,
> +				       struct device *dev)
> +{
> +	amd_iommu_detach_device(domain, dev);
> +
> +	return 0;
> +}
> +
>   const struct iommu_ops amd_iommu_ops = {
>   	.capable = amd_iommu_capable,
>   	.domain_alloc = amd_iommu_domain_alloc,
> @@ -2295,6 +2303,10 @@ const struct iommu_ops amd_iommu_ops = {
>   		.iotlb_sync	= amd_iommu_iotlb_sync,
>   		.free		= amd_iommu_domain_free,
>   		.enforce_cache_coherency = amd_iommu_enforce_cache_coherency,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= amd_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
> index a0b7281f1989..3c37762e01ec 100644
> --- a/drivers/iommu/apple-dart.c
> +++ b/drivers/iommu/apple-dart.c
> @@ -763,6 +763,14 @@ static void apple_dart_get_resv_regions(struct device *dev,
>   	iommu_dma_get_resv_regions(dev, head);
>   }
>   
> +static int apple_dart_blocking_domain_set_dev(struct iommu_domain *domain,
> +					      struct device *dev)
> +{
> +	apple_dart_detach_dev(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops apple_dart_iommu_ops = {
>   	.domain_alloc = apple_dart_domain_alloc,
>   	.probe_device = apple_dart_probe_device,
> @@ -784,6 +792,10 @@ static const struct iommu_ops apple_dart_iommu_ops = {
>   		.iotlb_sync_map	= apple_dart_iotlb_sync_map,
>   		.iova_to_phys	= apple_dart_iova_to_phys,
>   		.free		= apple_dart_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= apple_dart_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> 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 7e7d9e0b7aee..4b0ec5bef63b 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2867,6 +2867,9 @@ static struct iommu_ops arm_smmu_ops = {
>   		.iova_to_phys		= arm_smmu_iova_to_phys,
>   		.enable_nesting		= arm_smmu_enable_nesting,
>   		.free			= arm_smmu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev		= arm_smmu_attach_dev,
>   	}
>   };
>   
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index c91d12b7e283..0723f7c97763 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -1606,6 +1606,9 @@ static struct iommu_ops arm_smmu_ops = {
>   		.enable_nesting		= arm_smmu_enable_nesting,
>   		.set_pgtable_quirks	= arm_smmu_set_pgtable_quirks,
>   		.free			= arm_smmu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev		= arm_smmu_attach_dev,
>   	}
>   };
>   
> diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> index cf624bd305e0..dee9b5a3a324 100644
> --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
> @@ -587,6 +587,14 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
>   	return iommu_fwspec_add_ids(dev, &asid, 1);
>   }
>   
> +static int qcom_blocking_domain_set_dev(struct iommu_domain *domain,
> +					struct device *dev)
> +{
> +	qcom_iommu_detach_dev(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops qcom_iommu_ops = {
>   	.capable	= qcom_iommu_capable,
>   	.domain_alloc	= qcom_iommu_domain_alloc,
> @@ -604,6 +612,10 @@ static const struct iommu_ops qcom_iommu_ops = {
>   		.iotlb_sync	= qcom_iommu_iotlb_sync,
>   		.iova_to_phys	= qcom_iommu_iova_to_phys,
>   		.free		= qcom_iommu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= qcom_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index 797348f3440e..bbecb9a2a554 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -1307,6 +1307,14 @@ static int exynos_iommu_of_xlate(struct device *dev,
>   	return 0;
>   }
>   
> +static int exynos_blocking_domain_set_dev(struct iommu_domain *domain,
> +					  struct device *dev)
> +{
> +	exynos_iommu_detach_device(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops exynos_iommu_ops = {
>   	.domain_alloc = exynos_iommu_domain_alloc,
>   	.device_group = generic_device_group,
> @@ -1321,6 +1329,10 @@ static const struct iommu_ops exynos_iommu_ops = {
>   		.unmap		= exynos_iommu_unmap,
>   		.iova_to_phys	= exynos_iommu_iova_to_phys,
>   		.free		= exynos_iommu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= exynos_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
> index 7512c8e007e9..92fc320f8c83 100644
> --- a/drivers/iommu/fsl_pamu_domain.c
> +++ b/drivers/iommu/fsl_pamu_domain.c
> @@ -451,6 +451,14 @@ static void fsl_pamu_release_device(struct device *dev)
>   {
>   }
>   
> +static int fsl_pamu_blocking_domain_set_dev(struct iommu_domain *domain,
> +					    struct device *dev)
> +{
> +	fsl_pamu_detach_device(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops fsl_pamu_ops = {
>   	.capable	= fsl_pamu_capable,
>   	.domain_alloc	= fsl_pamu_domain_alloc,
> @@ -462,6 +470,10 @@ static const struct iommu_ops fsl_pamu_ops = {
>   		.detach_dev	= fsl_pamu_detach_device,
>   		.iova_to_phys	= fsl_pamu_iova_to_phys,
>   		.free		= fsl_pamu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= fsl_pamu_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index 6abc1fbbd461..2060e8a540b3 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -4904,6 +4904,14 @@ static void intel_iommu_iotlb_sync_map(struct iommu_domain *domain,
>   	}
>   }
>   
> +static int intel_blocking_domain_set_dev(struct iommu_domain *domain,
> +					 struct device *dev)
> +{
> +	intel_iommu_detach_device(domain, dev);
> +
> +	return 0;
> +}
> +
>   const struct iommu_ops intel_iommu_ops = {
>   	.capable		= intel_iommu_capable,
>   	.domain_alloc		= intel_iommu_domain_alloc,
> @@ -4935,6 +4943,10 @@ const struct iommu_ops intel_iommu_ops = {
>   		.iova_to_phys		= intel_iommu_iova_to_phys,
>   		.free			= intel_iommu_domain_free,
>   		.enforce_cache_coherency = intel_iommu_enforce_cache_coherency,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev		= intel_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
> index b361a4cff688..72982d1277c2 100644
> --- a/drivers/iommu/ipmmu-vmsa.c
> +++ b/drivers/iommu/ipmmu-vmsa.c
> @@ -867,6 +867,14 @@ static struct iommu_group *ipmmu_find_group(struct device *dev)
>   	return group;
>   }
>   
> +static int ipmmu_blocking_domain_set_dev(struct iommu_domain *domain,
> +					 struct device *dev)
> +{
> +	ipmmu_detach_device(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops ipmmu_ops = {
>   	.domain_alloc = ipmmu_domain_alloc,
>   	.probe_device = ipmmu_probe_device,
> @@ -885,6 +893,10 @@ static const struct iommu_ops ipmmu_ops = {
>   		.iotlb_sync	= ipmmu_iotlb_sync,
>   		.iova_to_phys	= ipmmu_iova_to_phys,
>   		.free		= ipmmu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= ipmmu_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
> index 569d36840b67..b0471d03db60 100644
> --- a/drivers/iommu/msm_iommu.c
> +++ b/drivers/iommu/msm_iommu.c
> @@ -674,6 +674,14 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
>   	return 0;
>   }
>   
> +static int msm_blocking_domain_set_dev(struct iommu_domain *domain,
> +				       struct device *dev)
> +{
> +	msm_iommu_detach_dev(domain, dev);
> +
> +	return 0;
> +}
> +
>   static struct iommu_ops msm_iommu_ops = {
>   	.domain_alloc = msm_iommu_domain_alloc,
>   	.probe_device = msm_iommu_probe_device,
> @@ -696,6 +704,10 @@ static struct iommu_ops msm_iommu_ops = {
>   		.iotlb_sync_map	= msm_iommu_sync_map,
>   		.iova_to_phys	= msm_iommu_iova_to_phys,
>   		.free		= msm_iommu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= msm_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 33ec401d40eb..cc8d80290498 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -926,6 +926,14 @@ static void mtk_iommu_get_resv_regions(struct device *dev,
>   	}
>   }
>   
> +static int mtk_blocking_domain_set_dev(struct iommu_domain *domain,
> +				       struct device *dev)
> +{
> +	mtk_iommu_detach_device(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops mtk_iommu_ops = {
>   	.domain_alloc	= mtk_iommu_domain_alloc,
>   	.probe_device	= mtk_iommu_probe_device,
> @@ -946,6 +954,10 @@ static const struct iommu_ops mtk_iommu_ops = {
>   		.iotlb_sync_map	= mtk_iommu_sync_map,
>   		.iova_to_phys	= mtk_iommu_iova_to_phys,
>   		.free		= mtk_iommu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= mtk_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index fb55802fb841..894d2526ba4c 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -584,6 +584,14 @@ static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data)
>   	return 0;
>   }
>   
> +static int mtk_blocking_domain_set_dev(struct iommu_domain *domain,
> +				       struct device *dev)
> +{
> +	mtk_iommu_v1_detach_device(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops mtk_iommu_v1_ops = {
>   	.domain_alloc	= mtk_iommu_v1_domain_alloc,
>   	.probe_device	= mtk_iommu_v1_probe_device,
> @@ -600,6 +608,10 @@ static const struct iommu_ops mtk_iommu_v1_ops = {
>   		.unmap		= mtk_iommu_v1_unmap,
>   		.iova_to_phys	= mtk_iommu_v1_iova_to_phys,
>   		.free		= mtk_iommu_v1_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= mtk_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
> index 6720dcb437a0..7e6ba6f1218d 100644
> --- a/drivers/iommu/omap-iommu.c
> +++ b/drivers/iommu/omap-iommu.c
> @@ -1732,6 +1732,14 @@ static struct iommu_group *omap_iommu_device_group(struct device *dev)
>   	return group;
>   }
>   
> +static int omap_blocking_domain_set_dev(struct iommu_domain *domain,
> +					struct device *dev)
> +{
> +	omap_iommu_detach_dev(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops omap_iommu_ops = {
>   	.domain_alloc	= omap_iommu_domain_alloc,
>   	.probe_device	= omap_iommu_probe_device,
> @@ -1745,6 +1753,10 @@ static const struct iommu_ops omap_iommu_ops = {
>   		.unmap		= omap_iommu_unmap,
>   		.iova_to_phys	= omap_iommu_iova_to_phys,
>   		.free		= omap_iommu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= omap_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index 0a4196c34179..29c803759a0b 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
> @@ -1185,6 +1185,14 @@ static int rk_iommu_of_xlate(struct device *dev,
>   	return 0;
>   }
>   
> +static int rk_blocking_domain_set_dev(struct iommu_domain *domain,
> +				      struct device *dev)
> +{
> +	rk_iommu_detach_device(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops rk_iommu_ops = {
>   	.domain_alloc = rk_iommu_domain_alloc,
>   	.probe_device = rk_iommu_probe_device,
> @@ -1199,6 +1207,10 @@ static const struct iommu_ops rk_iommu_ops = {
>   		.unmap		= rk_iommu_unmap,
>   		.iova_to_phys	= rk_iommu_iova_to_phys,
>   		.free		= rk_iommu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev	= rk_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
> index cde01c72f573..a03bff562a44 100644
> --- a/drivers/iommu/s390-iommu.c
> +++ b/drivers/iommu/s390-iommu.c
> @@ -360,6 +360,14 @@ void zpci_destroy_iommu(struct zpci_dev *zdev)
>   	iommu_device_sysfs_remove(&zdev->iommu_dev);
>   }
>   
> +static int s390_blocking_domain_set_dev(struct iommu_domain *domain,
> +					struct device *dev)
> +{
> +	s390_iommu_detach_device(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops s390_iommu_ops = {
>   	.capable = s390_iommu_capable,
>   	.domain_alloc = s390_domain_alloc,
> @@ -374,6 +382,10 @@ static const struct iommu_ops s390_iommu_ops = {
>   		.unmap		= s390_iommu_unmap,
>   		.iova_to_phys	= s390_iommu_iova_to_phys,
>   		.free		= s390_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev		= s390_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
> index 45b58845f5f8..ab62063cee5b 100644
> --- a/drivers/iommu/sprd-iommu.c
> +++ b/drivers/iommu/sprd-iommu.c
> @@ -413,6 +413,13 @@ static int sprd_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
>   	return 0;
>   }
>   
> +static int sprd_blocking_domain_set_dev(struct iommu_domain *domain,
> +					struct device *dev)
> +{
> +	sprd_iommu_detach_device(domain, dev);
> +
> +	return 0;
> +}
>   
>   static const struct iommu_ops sprd_iommu_ops = {
>   	.domain_alloc	= sprd_iommu_domain_alloc,
> @@ -431,6 +438,10 @@ static const struct iommu_ops sprd_iommu_ops = {
>   		.iotlb_sync	= sprd_iommu_sync,
>   		.iova_to_phys	= sprd_iommu_iova_to_phys,
>   		.free		= sprd_iommu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev		= sprd_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
> index 041b30463552..a51a55ae0634 100644
> --- a/drivers/iommu/sun50i-iommu.c
> +++ b/drivers/iommu/sun50i-iommu.c
> @@ -758,6 +758,14 @@ static int sun50i_iommu_of_xlate(struct device *dev,
>   	return iommu_fwspec_add_ids(dev, &id, 1);
>   }
>   
> +static int sun50i_blocking_domain_set_dev(struct iommu_domain *domain,
> +					  struct device *dev)
> +{
> +	sun50i_iommu_detach_device(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops sun50i_iommu_ops = {
>   	.pgsize_bitmap	= SZ_4K,
>   	.device_group	= sun50i_iommu_device_group,
> @@ -774,6 +782,10 @@ static const struct iommu_ops sun50i_iommu_ops = {
>   		.map		= sun50i_iommu_map,
>   		.unmap		= sun50i_iommu_unmap,
>   		.free		= sun50i_iommu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev		= sun50i_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
> index f083a9fba4d0..7e2aef7ae72e 100644
> --- a/drivers/iommu/tegra-gart.c
> +++ b/drivers/iommu/tegra-gart.c
> @@ -270,6 +270,14 @@ static void gart_iommu_sync(struct iommu_domain *domain,
>   	gart_iommu_sync_map(domain, gather->start, length);
>   }
>   
> +static int gart_blocking_domain_set_dev(struct iommu_domain *domain,
> +					struct device *dev)
> +{
> +	gart_iommu_detach_dev(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops gart_iommu_ops = {
>   	.domain_alloc	= gart_iommu_domain_alloc,
>   	.probe_device	= gart_iommu_probe_device,
> @@ -286,6 +294,10 @@ static const struct iommu_ops gart_iommu_ops = {
>   		.iotlb_sync_map	= gart_iommu_sync_map,
>   		.iotlb_sync	= gart_iommu_sync,
>   		.free		= gart_iommu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev		= gart_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> index 36e9c2864e3f..fe2c463db230 100644
> --- a/drivers/iommu/tegra-smmu.c
> +++ b/drivers/iommu/tegra-smmu.c
> @@ -963,6 +963,14 @@ static int tegra_smmu_of_xlate(struct device *dev,
>   	return iommu_fwspec_add_ids(dev, &id, 1);
>   }
>   
> +static int tegra_smmu_blocking_domain_set_dev(struct iommu_domain *domain,
> +					      struct device *dev)
> +{
> +	tegra_smmu_detach_dev(domain, dev);
> +
> +	return 0;
> +}
> +
>   static const struct iommu_ops tegra_smmu_ops = {
>   	.domain_alloc = tegra_smmu_domain_alloc,
>   	.probe_device = tegra_smmu_probe_device,
> @@ -977,6 +985,10 @@ static const struct iommu_ops tegra_smmu_ops = {
>   		.unmap		= tegra_smmu_unmap,
>   		.iova_to_phys	= tegra_smmu_iova_to_phys,
>   		.free		= tegra_smmu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev		= tegra_smmu_blocking_domain_set_dev,
> +		.blocking_domain_detach = true,
>   	}
>   };
>   
> diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
> index ce2bd01806d8..5054ebaf9654 100644
> --- a/drivers/iommu/virtio-iommu.c
> +++ b/drivers/iommu/virtio-iommu.c
> @@ -1023,6 +1023,9 @@ static struct iommu_ops viommu_ops = {
>   		.iova_to_phys		= viommu_iova_to_phys,
>   		.iotlb_sync		= viommu_iotlb_sync,
>   		.free			= viommu_domain_free,
> +	},
> +	.blocking_domain_ops = &(const struct iommu_domain_ops) {
> +		.set_dev		= viommu_attach_dev,
>   	}
>   };
>   

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ