From: Joerg Roedel <jroe...@suse.de>

Make use of the default domain and re-attach a device to it
when it is detached from another domain. Also enforce that a
device has to be in the default domain before it can be
attached to a different domain.

Signed-off-by: Joerg Roedel <jroe...@suse.de>
---
 drivers/iommu/iommu.c | 34 +++++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index b63a550..5080759 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -53,6 +53,7 @@ struct iommu_group {
        int id;
        unsigned dev_cnt;
        struct iommu_domain *default_domain;
+       struct iommu_domain *domain;
 };
 
 struct iommu_device {
@@ -1040,8 +1041,17 @@ static int iommu_group_do_attach_device(struct device 
*dev, void *data)
 
 int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
 {
-       return iommu_group_for_each_dev(group, domain,
-                                       iommu_group_do_attach_device);
+       int ret;
+
+       if (group->default_domain && group->domain != group->default_domain)
+               return -EBUSY;
+
+       ret = iommu_group_for_each_dev(group, domain,
+                                      iommu_group_do_attach_device);
+       if (ret == 0)
+               group->domain = domain;
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(iommu_attach_group);
 
@@ -1056,7 +1066,25 @@ static int iommu_group_do_detach_device(struct device 
*dev, void *data)
 
 void iommu_detach_group(struct iommu_domain *domain, struct iommu_group *group)
 {
-       iommu_group_for_each_dev(group, domain, iommu_group_do_detach_device);
+       int ret;
+
+       if (!group->default_domain) {
+               iommu_group_for_each_dev(group, domain,
+                                        iommu_group_do_detach_device);
+               group->domain = NULL;
+               return;
+       }
+
+       if (group->domain == group->default_domain)
+               return;
+
+       /* Detach by re-attaching to the default domain */
+       ret = iommu_group_for_each_dev(group, group->default_domain,
+                                      iommu_group_do_attach_device);
+       if (ret != 0)
+               WARN_ON(1);
+       else
+               group->domain = group->default_domain;
 }
 EXPORT_SYMBOL_GPL(iommu_detach_group);
 
-- 
1.9.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to