mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-13 22:14:20 +08:00
iommu: Allow an IDENTITY domain as the default_domain in ARM32
Even though dma-iommu.c and CONFIG_ARM_DMA_USE_IOMMU do approximately the same stuff, the way they relate to the IOMMU core is quiet different. dma-iommu.c expects the core code to setup an UNMANAGED domain (of type IOMMU_DOMAIN_DMA) and then configures itself to use that domain. This becomes the default_domain for the group. ARM_DMA_USE_IOMMU does not use the default_domain, instead it directly allocates an UNMANAGED domain and operates it just like an external driver. In this case group->default_domain is NULL. If the driver provides a global static identity_domain then automatically use it as the default_domain when in ARM_DMA_USE_IOMMU mode. This allows drivers that implemented default_domain == NULL as an IDENTITY translation to trivially get a properly labeled non-NULL default_domain on ARM32 configs. With this arrangment when ARM_DMA_USE_IOMMU wants to disconnect from the device the normal detach_domain flow will restore the IDENTITY domain as the default domain. Overall this makes attach_dev() of the IDENTITY domain called in the same places as detach_dev(). This effectively migrates these drivers to default_domain mode. For drivers that support ARM64 they will gain support for the IDENTITY translation mode for the dma_api and behave in a uniform way. Drivers use this by setting ops->identity_domain to a static singleton iommu_domain that implements the identity attach. If the core detects ARM_DMA_USE_IOMMU mode then it automatically attaches the IDENTITY domain during probe. Drivers can continue to prevent the use of DMA translation by returning IOMMU_DOMAIN_IDENTITY from def_domain_type, this will completely prevent IOMMU_DMA from running but will not impact ARM_DMA_USE_IOMMU. This allows removing the set_platform_dma_ops() from every remaining driver. Remove the set_platform_dma_ops from rockchip and mkt_v1 as all it does is set an existing global static identity domain. mkt_v1 does not support IOMMU_DOMAIN_DMA and it does not compile on ARM64 so this transformation is safe. Tested-by: Steven Price <steven.price@arm.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/9-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
59ddce4418
commit
e98befd010
@ -1865,17 +1865,36 @@ static int iommu_get_def_domain_type(struct iommu_group *group,
|
||||
static int iommu_get_default_domain_type(struct iommu_group *group,
|
||||
int target_type)
|
||||
{
|
||||
const struct iommu_ops *ops = group_iommu_ops(group);
|
||||
struct device *untrusted = NULL;
|
||||
struct group_device *gdev;
|
||||
int driver_type = 0;
|
||||
|
||||
lockdep_assert_held(&group->mutex);
|
||||
|
||||
/*
|
||||
* ARM32 drivers supporting CONFIG_ARM_DMA_USE_IOMMU can declare an
|
||||
* identity_domain and it will automatically become their default
|
||||
* domain. Later on ARM_DMA_USE_IOMMU will install its UNMANAGED domain.
|
||||
* Override the selection to IDENTITY if we are sure the driver supports
|
||||
* it.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) && ops->identity_domain)
|
||||
driver_type = IOMMU_DOMAIN_IDENTITY;
|
||||
|
||||
for_each_group_device(group, gdev) {
|
||||
driver_type = iommu_get_def_domain_type(group, gdev->dev,
|
||||
driver_type);
|
||||
|
||||
if (dev_is_pci(gdev->dev) && to_pci_dev(gdev->dev)->untrusted)
|
||||
if (dev_is_pci(gdev->dev) && to_pci_dev(gdev->dev)->untrusted) {
|
||||
/*
|
||||
* No ARM32 using systems will set untrusted, it cannot
|
||||
* work.
|
||||
*/
|
||||
if (WARN_ON(IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)))
|
||||
return -1;
|
||||
untrusted = gdev->dev;
|
||||
}
|
||||
}
|
||||
|
||||
if (untrusted) {
|
||||
|
@ -337,11 +337,6 @@ static struct iommu_domain mtk_iommu_v1_identity_domain = {
|
||||
.ops = &mtk_iommu_v1_identity_ops,
|
||||
};
|
||||
|
||||
static void mtk_iommu_v1_set_platform_dma(struct device *dev)
|
||||
{
|
||||
mtk_iommu_v1_identity_attach(&mtk_iommu_v1_identity_domain, dev);
|
||||
}
|
||||
|
||||
static int mtk_iommu_v1_map(struct iommu_domain *domain, unsigned long iova,
|
||||
phys_addr_t paddr, size_t pgsize, size_t pgcount,
|
||||
int prot, gfp_t gfp, size_t *mapped)
|
||||
@ -457,11 +452,6 @@ static int mtk_iommu_v1_create_mapping(struct device *dev, struct of_phandle_arg
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_iommu_v1_def_domain_type(struct device *dev)
|
||||
{
|
||||
return IOMMU_DOMAIN_IDENTITY;
|
||||
}
|
||||
|
||||
static struct iommu_device *mtk_iommu_v1_probe_device(struct device *dev)
|
||||
{
|
||||
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
|
||||
@ -599,10 +589,8 @@ static const struct iommu_ops mtk_iommu_v1_ops = {
|
||||
.probe_device = mtk_iommu_v1_probe_device,
|
||||
.probe_finalize = mtk_iommu_v1_probe_finalize,
|
||||
.release_device = mtk_iommu_v1_release_device,
|
||||
.def_domain_type = mtk_iommu_v1_def_domain_type,
|
||||
.device_group = generic_device_group,
|
||||
.pgsize_bitmap = MT2701_IOMMU_PAGE_SIZE,
|
||||
.set_platform_dma_ops = mtk_iommu_v1_set_platform_dma,
|
||||
.owner = THIS_MODULE,
|
||||
.default_domain_ops = &(const struct iommu_domain_ops) {
|
||||
.attach_dev = mtk_iommu_v1_attach_device,
|
||||
|
@ -998,13 +998,6 @@ static struct iommu_domain rk_identity_domain = {
|
||||
.ops = &rk_identity_ops,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
static void rk_iommu_set_platform_dma(struct device *dev)
|
||||
{
|
||||
WARN_ON(rk_iommu_identity_attach(&rk_identity_domain, dev));
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rk_iommu_attach_device(struct iommu_domain *domain,
|
||||
struct device *dev)
|
||||
{
|
||||
@ -1183,9 +1176,6 @@ static const struct iommu_ops rk_iommu_ops = {
|
||||
.probe_device = rk_iommu_probe_device,
|
||||
.release_device = rk_iommu_release_device,
|
||||
.device_group = rk_iommu_device_group,
|
||||
#ifdef CONFIG_ARM
|
||||
.set_platform_dma_ops = rk_iommu_set_platform_dma,
|
||||
#endif
|
||||
.pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP,
|
||||
.of_xlate = rk_iommu_of_xlate,
|
||||
.default_domain_ops = &(const struct iommu_domain_ops) {
|
||||
|
Loading…
Reference in New Issue
Block a user