[RFC,11/12] iommu/vt-d: Use intel_iommu_set_dev_pasid() for sva domain
Commit Message
Let intel_svm_set_dev_pasid() use intel_iommu_set_dev_pasid() for
set_dev_pasid operation.
Signed-off-by: Tina Zhang <tina.zhang@intel.com>
---
drivers/iommu/intel/svm.c | 44 +++++++--------------------------------
1 file changed, 8 insertions(+), 36 deletions(-)
@@ -231,13 +231,9 @@ static const struct mmu_notifier_ops intel_mmuops = {
static int intel_svm_set_dev_pasid(struct iommu_domain *domain,
struct device *dev, ioasid_t pasid)
{
- struct dmar_domain *dmar_domain = to_dmar_domain(domain);
- struct device_domain_info *info = dev_iommu_priv_get(dev);
- struct intel_iommu *iommu = info->iommu;
struct mm_struct *mm = domain->mm;
- struct dev_pasid_info *dev_pasid;
- unsigned long sflags;
- int ret = 0;
+ struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+ int ret;
/*
* The sva domain can be shared among multiple devices. Make sure
@@ -250,37 +246,11 @@ static int intel_svm_set_dev_pasid(struct iommu_domain *domain,
return ret;
}
- dev_pasid = kzalloc(sizeof(*dev_pasid), GFP_KERNEL);
- if (!dev_pasid) {
- ret = -ENOMEM;
- goto out_unregister;
- }
-
- dev_pasid->dev = dev;
- dev_pasid->sid = PCI_DEVID(info->bus, info->devfn);
- if (info->ats_enabled) {
- dev_pasid->qdep = info->ats_qdep;
- if (dev_pasid->qdep >= QI_DEV_EIOTLB_MAX_INVS)
- dev_pasid->qdep = 0;
+ ret = intel_iommu_set_dev_pasid(domain, dev, pasid);
+ if (ret) {
+ if (list_empty(&dmar_domain->dev_pasids))
+ mmu_notifier_unregister(&domain->notifier, mm);
}
-
- /* Setup the pasid table: */
- sflags = cpu_feature_enabled(X86_FEATURE_LA57) ? PASID_FLAG_FL5LP : 0;
- ret = intel_pasid_setup_first_level(iommu, dev, mm->pgd, pasid,
- FLPT_DEFAULT_DID, sflags);
- if (ret)
- goto out_free_dev_pasid;
-
- list_add_rcu(&dev_pasid->link_domain, &dmar_domain->dev_pasids);
-
- return 0;
-
-out_free_dev_pasid:
- kfree(dev_pasid);
-out_unregister:
- if (list_empty(&dmar_domain->dev_pasids))
- mmu_notifier_unregister(&domain->notifier, mm);
-
return ret;
}
@@ -696,6 +666,8 @@ struct iommu_domain *intel_svm_domain_alloc(void)
return NULL;
domain->domain.ops = &intel_svm_domain_ops;
INIT_LIST_HEAD(&domain->dev_pasids);
+ spin_lock_init(&domain->lock);
+ xa_init(&domain->iommu_array);
return &domain->domain;
}