@@ -1640,6 +1640,17 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
lockdep_assert_held(&group->mutex);
+ /*
+ * Allow legacy drivers to specify the domain that will be the default
+ * domain. This should always be either an IDENTITY or PLATFORM domain.
+ * Do not use in new drivers.
+ */
+ if (bus->iommu_ops->default_domain) {
+ if (req_type)
+ return ERR_PTR(-EINVAL);
+ return bus->iommu_ops->default_domain;
+ }
+
if (req_type)
return __iommu_group_alloc_default_domain(bus, group, req_type);
@@ -1945,7 +1956,8 @@ void iommu_domain_free(struct iommu_domain *domain)
if (domain->type == IOMMU_DOMAIN_SVA)
mmdrop(domain->mm);
iommu_put_dma_cookie(domain);
- domain->ops->free(domain);
+ if (domain->ops->free)
+ domain->ops->free(domain);
}
EXPORT_SYMBOL_GPL(iommu_domain_free);
@@ -64,6 +64,7 @@ struct iommu_domain_geometry {
#define __IOMMU_DOMAIN_DMA_FQ (1U << 3) /* DMA-API uses flush queue */
#define __IOMMU_DOMAIN_SVA (1U << 4) /* Shared process address space */
+#define __IOMMU_DOMAIN_PLATFORM (1U << 5)
/*
* This are the possible domain-types
@@ -80,6 +81,8 @@ struct iommu_domain_geometry {
* invalidation.
* IOMMU_DOMAIN_SVA - DMA addresses are shared process addresses
* represented by mm_struct's.
+ * IOMMU_DOMAIN_PLATFORM - Legacy domain for drivers that do their own
+ * dma_api stuff. Do not use in new drivers.
*/
#define IOMMU_DOMAIN_BLOCKED (0U)
#define IOMMU_DOMAIN_IDENTITY (__IOMMU_DOMAIN_PT)
@@ -90,6 +93,7 @@ struct iommu_domain_geometry {
__IOMMU_DOMAIN_DMA_API | \
__IOMMU_DOMAIN_DMA_FQ)
#define IOMMU_DOMAIN_SVA (__IOMMU_DOMAIN_SVA)
+#define IOMMU_DOMAIN_PLATFORM (__IOMMU_DOMAIN_PLATFORM)
struct iommu_domain {
unsigned type;
@@ -248,6 +252,7 @@ struct iommu_iotlb_gather {
* will be blocked by the hardware.
* @pgsize_bitmap: bitmap of all possible supported page sizes
* @owner: Driver module providing these ops
+ * @default_domain: If not NULL this will always be set as the default domain.
*/
struct iommu_ops {
bool (*capable)(struct device *dev, enum iommu_cap);
@@ -281,6 +286,7 @@ struct iommu_ops {
const struct iommu_domain_ops *default_domain_ops;
unsigned long pgsize_bitmap;
struct module *owner;
+ struct iommu_domain *default_domain;
};
/**
This is an opaque domain type that is an escape hatch for tegra-gart and fsl_pamu that we can't figure out how to convert into actual BLOCKING or IDENTITY domains. It is designed to preserve the original ops->detach_dev() semantic that these drivers were built around. The PLATFORM domain will be set as the default domain and attached as normal during probe. The drivers will ignore the initial attach from a NULL domain to the PLATFORM domain. After this, the PLATFORM domain's attach_dev will be called whenever we detach from an UNMANAGED domain (eg for VFIO). This is the same time the original design would have called op->detach_dev(). Add an ops->default_domain member so drivers can trivially opt into this mode. Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> --- drivers/iommu/iommu.c | 14 +++++++++++++- include/linux/iommu.h | 6 ++++++ 2 files changed, 19 insertions(+), 1 deletion(-)