The normal domain at(de)tach is parallel with aux-domain at(de)tach. In
another word, once an iommu_group is attached through the normal domain
attach api's, it should not go through the aux-domain at(de)tach api's
until the domain is detached. And, vice versa.

Currently, we prohibit an iommu_group to go through aux-domain api's if
group->domain != NULL; but we don't check aux-domain attachment in the
normal attach api's. This marks an iommu_group after an aux-domain is
attached, so that normal domain at(de)tach api's should never be used
after that.

Cc: Robin Murphy <robin.mur...@arm.com>
Signed-off-by: Lu Baolu <baolu...@linux.intel.com>
---
 drivers/iommu/iommu.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 435835058209..3e7489ea2010 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -45,6 +45,7 @@ struct iommu_group {
        struct iommu_domain *default_domain;
        struct iommu_domain *domain;
        struct list_head entry;
+       unsigned int aux_domain_attached:1;
 };
 
 struct group_device {
@@ -2074,6 +2075,9 @@ static int __iommu_attach_group(struct iommu_domain 
*domain,
 {
        int ret;
 
+       if (group->aux_domain_attached)
+               return -EINVAL;
+
        if (group->default_domain && group->domain != group->default_domain)
                return -EBUSY;
 
@@ -2111,6 +2115,9 @@ static void __iommu_detach_group(struct iommu_domain 
*domain,
 {
        int ret;
 
+       if (WARN_ON(group->aux_domain_attached))
+               return;
+
        if (!group->default_domain) {
                __iommu_group_for_each_dev(group, domain,
                                           iommu_group_do_detach_device);
@@ -2769,6 +2776,7 @@ int iommu_aux_attach_device(struct iommu_domain *domain,
        if (!ret) {
                trace_attach_device_to_domain(phys_dev);
                group->domain = domain;
+               group->aux_domain_attached = true;
        }
 
 out_unlock:
@@ -2802,8 +2810,12 @@ void iommu_aux_detach_device(struct iommu_domain *domain,
        if (WARN_ON(iommu_group_device_count(group) != 1))
                goto out_unlock;
 
+       if (WARN_ON(!group->aux_domain_attached))
+               goto out_unlock;
+
        domain->ops->aux_detach_dev(domain, phys_dev);
        group->domain = NULL;
+       group->aux_domain_attached = false;
        trace_detach_device_from_domain(phys_dev);
 
 out_unlock:
-- 
2.17.1

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

Reply via email to