>From IOMMU p.o.v., PASIDs allocated and managed by external components
(e.g. VFIO) will be passed in for gpasid_bind/unbind operation. IOMMU
needs some knowledge to check the PASID ownership, hence add an interface
for those components to tell the PASID owner.

In latest kernel design, PASID ownership is managed by IOASID set where
the PASID is allocated from. This patch adds support for setting ioasid
set ID to the domains used for nesting/vSVA. Subsequent SVA operations
will check the PASID against its IOASID set for proper ownership.

Cc: Kevin Tian <kevin.t...@intel.com>
CC: Jacob Pan <jacob.jun....@linux.intel.com>
Cc: Alex Williamson <alex.william...@redhat.com>
Cc: Eric Auger <eric.au...@redhat.com>
Cc: Jean-Philippe Brucker <jean-phili...@linaro.org>
Cc: Joerg Roedel <j...@8bytes.org>
Cc: Lu Baolu <baolu...@linux.intel.com>
Signed-off-by: Liu Yi L <yi.l....@intel.com>
Signed-off-by: Jacob Pan <jacob.jun....@linux.intel.com>
---
v6 -> v7:
*) add a helper function __domain_config_ioasid_set() per Eric's comment.
*) rename @ioasid_sid field of struct dmar_domain to be @pasid_set.
*) Eric gave r-b against v6, but since there is change, so will seek for his
   r-b again on this version.

v5 -> v6:
*) address comments against v5 from Eric Auger.

v4 -> v5:
*) address comments from Eric Auger.
---
 drivers/iommu/intel/iommu.c | 26 ++++++++++++++++++++++++++
 include/linux/intel-iommu.h |  4 ++++
 include/linux/iommu.h       |  1 +
 3 files changed, 31 insertions(+)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 5813eea..d1c77fc 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1806,6 +1806,7 @@ static struct dmar_domain *alloc_domain(int flags)
        if (first_level_by_default())
                domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
        domain->has_iotlb_device = false;
+       domain->pasid_set = host_pasid_set;
        INIT_LIST_HEAD(&domain->devices);
 
        return domain;
@@ -6007,6 +6008,22 @@ static bool intel_iommu_is_attach_deferred(struct 
iommu_domain *domain,
        return attach_deferred(dev);
 }
 
+static int __domain_config_ioasid_set(struct dmar_domain *domain,
+                                     struct ioasid_set *set)
+{
+       if (!(domain->flags & DOMAIN_FLAG_NESTING_MODE))
+               return -ENODEV;
+
+       if (domain->pasid_set != host_pasid_set &&
+           domain->pasid_set != set) {
+               pr_warn_ratelimited("multi ioasid_set setting to domain");
+               return -EBUSY;
+       }
+
+       domain->pasid_set = set;
+       return 0;
+}
+
 static int
 intel_iommu_domain_set_attr(struct iommu_domain *domain,
                            enum iommu_attr attr, void *data)
@@ -6030,6 +6047,15 @@ intel_iommu_domain_set_attr(struct iommu_domain *domain,
                }
                spin_unlock_irqrestore(&device_domain_lock, flags);
                break;
+       case DOMAIN_ATTR_IOASID_SET:
+       {
+               struct ioasid_set *set = (struct ioasid_set *)data;
+
+               spin_lock_irqsave(&device_domain_lock, flags);
+               ret = __domain_config_ioasid_set(dmar_domain, set);
+               spin_unlock_irqrestore(&device_domain_lock, flags);
+               break;
+       }
        default:
                ret = -EINVAL;
                break;
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index d36038e..3345391 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -549,6 +549,10 @@ struct dmar_domain {
                                           2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
        u64             max_addr;       /* maximum mapped address */
 
+       struct ioasid_set *pasid_set;   /*
+                                        * the ioasid set which tracks all
+                                        * PASIDs used by the domain.
+                                        */
        int             default_pasid;  /*
                                         * The default pasid used for non-SVM
                                         * traffic on mediated devices.
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c364b1c..5b9f630 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -118,6 +118,7 @@ enum iommu_attr {
        DOMAIN_ATTR_FSL_PAMUV1,
        DOMAIN_ATTR_NESTING,    /* two stages of translation */
        DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE,
+       DOMAIN_ATTR_IOASID_SET,
        DOMAIN_ATTR_MAX,
 };
 
-- 
2.7.4

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

Reply via email to