* [PATCH] iommu/exynos: Implement an IDENTITY domain
@ 2023-04-06 23:42 Jason Gunthorpe
2023-05-19 15:39 ` Jason Gunthorpe
0 siblings, 1 reply; 2+ messages in thread
From: Jason Gunthorpe @ 2023-04-06 23:42 UTC (permalink / raw)
To: Alim Akhtar, iommu, Joerg Roedel, Krzysztof Kozlowski,
linux-arm-kernel, linux-samsung-soc, Marek Szyprowski,
Robin Murphy, Will Deacon
What exynos calls exynos_iommu_detach_device is actually putting the iommu
into identity mode. Instead of having a translation mode that is invisible
to the core code implement it as an actual IDENTITY domain.
On ARM64 this will allow the IDENTITIY dma iommu mode to work, and on
ARM32 this clarifies what set_platform_dma_ops is actually doing.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/iommu/exynos-iommu.c | 67 ++++++++++++++++++++++--------------
1 file changed, 42 insertions(+), 25 deletions(-)
Marek, as requested here is that patch on top of your stuff that went to rc
I picked all the notes from Steve from the rockchip version into here as well
Thanks,
Jason
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 1abd187c6075e4..acdb8aeeed48b4 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -24,6 +24,7 @@
typedef u32 sysmmu_iova_t;
typedef u32 sysmmu_pte_t;
+static struct iommu_domain exynos_identity_domain;
/* We do not consider super section mapping (16MB) */
#define SECT_ORDER 20
@@ -837,7 +838,7 @@ static int __maybe_unused exynos_sysmmu_suspend(struct device *dev)
struct exynos_iommu_owner *owner = dev_iommu_priv_get(master);
mutex_lock(&owner->rpm_lock);
- if (data->domain) {
+ if (&data->domain->domain != &exynos_identity_domain) {
dev_dbg(data->sysmmu, "saving state\n");
__sysmmu_disable(data);
}
@@ -855,7 +856,7 @@ static int __maybe_unused exynos_sysmmu_resume(struct device *dev)
struct exynos_iommu_owner *owner = dev_iommu_priv_get(master);
mutex_lock(&owner->rpm_lock);
- if (data->domain) {
+ if (&data->domain->domain != &exynos_identity_domain) {
dev_dbg(data->sysmmu, "restoring state\n");
__sysmmu_enable(data);
}
@@ -900,6 +901,9 @@ static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
dma_addr_t handle;
int i;
+ if (type == IOMMU_DOMAIN_IDENTITY)
+ return &exynos_identity_domain;
+
/* Check if correct PTE offsets are initialized */
BUG_ON(PG_ENT_SHIFT < 0 || !dma_dev);
@@ -988,17 +992,22 @@ static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain)
kfree(domain);
}
-static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
- struct device *dev)
+static int exynos_iommu_identity_attach(struct iommu_domain *identity_domain,
+ struct device *dev)
{
- struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
- phys_addr_t pagetable = virt_to_phys(domain->pgtable);
+ struct exynos_iommu_domain *domain;
+ phys_addr_t pagetable;
struct sysmmu_drvdata *data, *next;
unsigned long flags;
- if (!has_sysmmu(dev) || owner->domain != iommu_domain)
- return;
+ if (!owner)
+ return -ENODEV;
+ if (owner->domain == identity_domain)
+ return 0;
+
+ domain = to_exynos_domain(owner->domain);
+ pagetable = virt_to_phys(domain->pgtable);
mutex_lock(&owner->rpm_lock);
@@ -1017,15 +1026,30 @@ static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
list_del_init(&data->domain_node);
spin_unlock(&data->lock);
}
- owner->domain = NULL;
+ owner->domain = identity_domain;
spin_unlock_irqrestore(&domain->lock, flags);
mutex_unlock(&owner->rpm_lock);
dev_dbg(dev, "%s: Detached IOMMU with pgtable %pa\n", __func__,
&pagetable);
+ return 0;
+}
+
+static void exynos_iommu_identity_free(struct iommu_domain *domain)
+{
}
+static struct iommu_domain_ops exynos_identity_ops = {
+ .attach_dev = exynos_iommu_identity_attach,
+ .free = exynos_iommu_identity_free,
+};
+
+static struct iommu_domain exynos_identity_domain = {
+ .type = IOMMU_DOMAIN_IDENTITY,
+ .ops = &exynos_identity_ops,
+};
+
static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
struct device *dev)
{
@@ -1034,12 +1058,11 @@ static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
struct sysmmu_drvdata *data;
phys_addr_t pagetable = virt_to_phys(domain->pgtable);
unsigned long flags;
+ int err;
- if (!has_sysmmu(dev))
- return -ENODEV;
-
- if (owner->domain)
- exynos_iommu_detach_device(owner->domain, dev);
+ err = exynos_iommu_identity_attach(&exynos_identity_domain, dev);
+ if (err)
+ return err;
mutex_lock(&owner->rpm_lock);
@@ -1415,26 +1438,19 @@ static struct iommu_device *exynos_iommu_probe_device(struct device *dev)
return &data->iommu;
}
+#ifdef CONFIG_ARM
static void exynos_iommu_set_platform_dma(struct device *dev)
{
- struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
-
- if (owner->domain) {
- struct iommu_group *group = iommu_group_get(dev);
-
- if (group) {
- exynos_iommu_detach_device(owner->domain, dev);
- iommu_group_put(group);
- }
- }
+ WARN_ON(exynos_iommu_identity_attach(&exynos_identity_domain, dev));
}
+#endif
static void exynos_iommu_release_device(struct device *dev)
{
struct exynos_iommu_owner *owner = dev_iommu_priv_get(dev);
struct sysmmu_drvdata *data;
- exynos_iommu_set_platform_dma(dev);
+ WARN_ON(exynos_iommu_identity_attach(&exynos_identity_domain, dev));
list_for_each_entry(data, &owner->controllers, owner_node)
device_link_del(data->link);
@@ -1465,6 +1481,7 @@ static int exynos_iommu_of_xlate(struct device *dev,
INIT_LIST_HEAD(&owner->controllers);
mutex_init(&owner->rpm_lock);
+ owner->domain = &exynos_identity_domain;
dev_iommu_priv_set(dev, owner);
}
base-commit: 13a0d1ae7ee6b438f5537711a8c60cba00554943
--
2.40.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] iommu/exynos: Implement an IDENTITY domain
2023-04-06 23:42 [PATCH] iommu/exynos: Implement an IDENTITY domain Jason Gunthorpe
@ 2023-05-19 15:39 ` Jason Gunthorpe
0 siblings, 0 replies; 2+ messages in thread
From: Jason Gunthorpe @ 2023-05-19 15:39 UTC (permalink / raw)
To: Alim Akhtar, iommu, Joerg Roedel, Krzysztof Kozlowski,
linux-arm-kernel, linux-samsung-soc, Marek Szyprowski,
Robin Murphy, Will Deacon
On Thu, Apr 06, 2023 at 08:42:57PM -0300, Jason Gunthorpe wrote:
> What exynos calls exynos_iommu_detach_device is actually putting the iommu
> into identity mode. Instead of having a translation mode that is invisible
> to the core code implement it as an actual IDENTITY domain.
>
> On ARM64 this will allow the IDENTITIY dma iommu mode to work, and on
> ARM32 this clarifies what set_platform_dma_ops is actually doing.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
> drivers/iommu/exynos-iommu.c | 67 ++++++++++++++++++++++--------------
> 1 file changed, 42 insertions(+), 25 deletions(-)
>
> Marek, as requested here is that patch on top of your stuff that went to rc
Just for clarity this patch was superseded by this series where it is patch
10:
https://lore.kernel.org/linux-iommu/0-v2-8d1dc464eac9+10f-iommu_all_defdom_jgg@nvidia.com
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-05-19 15:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-06 23:42 [PATCH] iommu/exynos: Implement an IDENTITY domain Jason Gunthorpe
2023-05-19 15:39 ` Jason Gunthorpe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).