Re: [PATCH v6 00/25] iommu: Make default_domain's mandatory

Baolu Lu
2023-08-14T08:45:03Z

On 2023/8/3 8:07, Jason Gunthorpe wrote:
> [ It would be good to get this in linux-next, we have some good test
> coverage on the ARM side already, thanks! ]
>
> It has been a long time coming, this series completes the default_domain
> transition and makes it so that the core IOMMU code will always have a
> non-NULL default_domain for every driver on every
> platform. set_platform_dma_ops() turned out to be a bad idea, and so
> completely remove it.
>
> This is achieved by changing each driver to either:
>
> 1 - Convert the existing (or deleted) ops->detach_dev() into an
> op->attach_dev() of an IDENTITY domain.
>
> This is based on the theory that the ARM32 HW is able to function when
> the iommu is turned off and so the turned off state is an IDENTITY
> translation.
>
> 2 - Use a new PLATFORM domain type. This is a hack to accommodate drivers
> that we don't really know WTF they do. S390 is legitimately using this
> to switch to it's platform dma_ops implementation, which is where the
> name comes from.
>
> 3 - Do #1 and force the default domain to be IDENTITY, this corrects
> the tegra-smmu case where even an ARM64 system would have a NULL
> default_domain.
>
> Using this we can apply the rules:
>
> a) ARM_DMA_USE_IOMMU mode always uses either the driver's
> ops->default_domain, ops->def_domain_type(), or an IDENTITY domain.
> All ARM32 drivers provide one of these three options.
>
> b) dma-iommu.c mode uses either the driver's ops->default_domain,
> ops->def_domain_type or the usual DMA API policy logic based on the
> command line/etc to pick IDENTITY/DMA domain types
>
> c) All other arch's (PPC/S390) use ops->default_domain always.
>
> See the patch "Require a default_domain for all iommu drivers" for a
> per-driver breakdown.
>
> The conversion broadly teaches a bunch of ARM32 drivers that they can do
> IDENTITY domains. There is some educated guessing involved that these are
> actual IDENTITY domains. If this turns out to be wrong the driver can be
> trivially changed to use a BLOCKING domain type instead. Further, the
> domain type only matters for drivers using ARM64's dma-iommu.c mode as it
> will select IDENTITY based on the command line and expect IDENTITY to
> work. For ARM32 and other arch cases it is purely documentation.
>
> Finally, based on all the analysis in this series, we can purge
> IOMMU_DOMAIN_UNMANAGED/DMA constants from most of the drivers. This
> greatly simplifies understanding the driver contract to the core
> code. IOMMU drivers should not be involved in policy for how the DMA API
> works, that should be a core core decision.
>
> The main gain from this work is to remove alot of ARM_DMA_USE_IOMMU
> specific code and behaviors from drivers. All that remains in iommu
> drivers after this series is the calls to arm_iommu_create_mapping().
>
> This is a step toward removing ARM_DMA_USE_IOMMU.
>
> The IDENTITY domains added to the ARM64 supporting drivers can be tested
> by booting in ARM64 mode and enabling CONFIG_IOMMU_DEFAULT_PASSTHROUGH. If
> the system still boots then most likely the implementation is an IDENTITY
> domain. If not we can trivially change it to BLOCKING or at worst PLATFORM
> if there is no detail what is going on in the HW.
>
> I think this is pretty safe for the ARM32 drivers as they don't really
> change, the code that was in detach_dev continues to be called in the same
> places it was called before.
>
> This is on github:https://github.com/jgunthorpe/linux/commits/iommu_all_defdom

It seems that after this series, all ARM iommu drivers are able to
support the IDENTITY default domain, hence perhaps we can remove below
code?

If I remember it correctly, the background of this part of code is
that some arm drivers didn't support IDENTITY domain, so fall back to
DMA domain if IDENTITY domain allocation fails.

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ddbba3ffbfbd..ee1fa63f0612 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1798,7 +1798,6 @@ iommu_group_alloc_default_domain(struct
iommu_group *group, int req_type)
list_first_entry(&group->devices, struct group_device, list)
->dev;
const struct iommu_ops *ops = dev_iommu_ops(dev);
- struct iommu_domain *dom;

lockdep_assert_held(&group->mutex);

@@ -1817,20 +1816,7 @@ iommu_group_alloc_default_domain(struct
iommu_group *group, int req_type)
return __iommu_group_alloc_default_domain(group, req_type);

/* The driver gave no guidance on what type to use, try the default */
- dom = __iommu_group_alloc_default_domain(group, iommu_def_domain_type);
- if (dom)
- return dom;
-
- /* Otherwise IDENTITY and DMA_FQ defaults will try DMA */
- if (iommu_def_domain_type == IOMMU_DOMAIN_DMA)
- return NULL;
- dom = __iommu_group_alloc_default_domain(group, IOMMU_DOMAIN_DMA);
- if (!dom)
- return NULL;
-
- pr_warn("Failed to allocate default IOMMU domain of type %u for group
%s - Falling back to IOMMU_DOMAIN_DMA",
- iommu_def_domain_type, group->name);
- return dom;
+ return __iommu_group_alloc_default_domain(group, iommu_def_domain_type);
}

struct iommu_domain *iommu_group_default_domain(struct iommu_group *group)

Best regards,
baolu