Add support for domain ops callbacks for an SVA domain. Signed-off-by: Lu Baolu <baolu...@linux.intel.com> --- include/linux/intel-iommu.h | 4 ++++ drivers/iommu/intel/iommu.c | 4 ++++ drivers/iommu/intel/svm.c | 37 ++++++++++++++++++++++++++++++++----- 3 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index df23300cfa88..5e88eaa245aa 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -744,6 +744,10 @@ void intel_svm_unbind(struct iommu_sva *handle); u32 intel_svm_get_pasid(struct iommu_sva *handle); int intel_svm_page_response(struct device *dev, struct iommu_fault_event *evt, struct iommu_page_response *msg); +int intel_svm_attach_dev_pasid(struct iommu_domain *domain, + struct device *dev, ioasid_t pasid); +void intel_svm_detach_dev_pasid(struct iommu_domain *domain, + struct device *dev, ioasid_t pasid); struct intel_svm_dev { struct list_head list; diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index e56b3a4b6998..2b6a52c87c73 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4923,6 +4923,10 @@ const struct iommu_ops intel_iommu_ops = { .sva_unbind = intel_svm_unbind, .sva_get_pasid = intel_svm_get_pasid, .page_response = intel_svm_page_response, + .sva_domain_ops = &(const struct iommu_domain_ops) { + .set_dev_pasid = intel_svm_attach_dev_pasid, + .block_dev_pasid = intel_svm_detach_dev_pasid, + }, #endif .default_domain_ops = &(const struct iommu_domain_ops) { .attach_dev = intel_iommu_attach_device, diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c index d04880a291c3..d575792441f3 100644 --- a/drivers/iommu/intel/svm.c +++ b/drivers/iommu/intel/svm.c @@ -323,6 +323,7 @@ static int intel_svm_alloc_pasid(struct device *dev, struct mm_struct *mm) static struct iommu_sva *intel_svm_bind_mm(struct intel_iommu *iommu, struct device *dev, + ioasid_t pasid, struct mm_struct *mm) { struct device_domain_info *info = dev_iommu_priv_get(dev); @@ -331,13 +332,13 @@ static struct iommu_sva *intel_svm_bind_mm(struct intel_iommu *iommu, struct intel_svm *svm; int ret = 0; - svm = pasid_private_find(mm->pasid); + svm = pasid_private_find(pasid); if (!svm) { svm = kzalloc(sizeof(*svm), GFP_KERNEL); if (!svm) return ERR_PTR(-ENOMEM); - svm->pasid = mm->pasid; + svm->pasid = pasid; svm->mm = mm; INIT_LIST_HEAD_RCU(&svm->devs); @@ -387,7 +388,7 @@ static struct iommu_sva *intel_svm_bind_mm(struct intel_iommu *iommu, /* Setup the pasid table: */ sflags = cpu_feature_enabled(X86_FEATURE_LA57) ? PASID_FLAG_FL5LP : 0; spin_lock_irqsave(&iommu->lock, iflags); - ret = intel_pasid_setup_first_level(iommu, dev, mm->pgd, mm->pasid, + ret = intel_pasid_setup_first_level(iommu, dev, mm->pgd, pasid, FLPT_DEFAULT_DID, sflags); spin_unlock_irqrestore(&iommu->lock, iflags); @@ -403,7 +404,7 @@ static struct iommu_sva *intel_svm_bind_mm(struct intel_iommu *iommu, free_svm: if (list_empty(&svm->devs)) { mmu_notifier_unregister(&svm->notifier, mm); - pasid_private_remove(mm->pasid); + pasid_private_remove(pasid); kfree(svm); } @@ -822,7 +823,7 @@ struct iommu_sva *intel_svm_bind(struct device *dev, struct mm_struct *mm) return ERR_PTR(ret); } - sva = intel_svm_bind_mm(iommu, dev, mm); + sva = intel_svm_bind_mm(iommu, dev, mm->pasid, mm); mutex_unlock(&pasid_mutex); return sva; @@ -931,3 +932,29 @@ int intel_svm_page_response(struct device *dev, mutex_unlock(&pasid_mutex); return ret; } + +int intel_svm_attach_dev_pasid(struct iommu_domain *domain, + struct device *dev, ioasid_t pasid) +{ + struct device_domain_info *info = dev_iommu_priv_get(dev); + struct mm_struct *mm = domain_to_mm(domain); + struct intel_iommu *iommu = info->iommu; + struct iommu_sva *sva; + int ret = 0; + + mutex_lock(&pasid_mutex); + sva = intel_svm_bind_mm(iommu, dev, pasid, mm); + if (IS_ERR(sva)) + ret = PTR_ERR(sva); + mutex_unlock(&pasid_mutex); + + return ret; +} + +void intel_svm_detach_dev_pasid(struct iommu_domain *domain, + struct device *dev, ioasid_t pasid) +{ + mutex_lock(&pasid_mutex); + intel_svm_unbind_mm(dev, pasid); + mutex_unlock(&pasid_mutex); +} -- 2.25.1 _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu