Since domain centralizes info required for sva domain in itself, the intel_iommu_remove_dev_pasid() can handle device detaching work of sva domain w/o asking help of intel_svm_remove_dev_pasid() any more. Signed-off-by: Tina Zhang <tina.zhang@xxxxxxxxx> --- drivers/iommu/intel/iommu.c | 16 +++++---------- drivers/iommu/intel/iommu.h | 4 ---- drivers/iommu/intel/svm.c | 39 ------------------------------------- 3 files changed, 5 insertions(+), 54 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 57f6bbf33205..2aea5201de3d 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4703,19 +4703,9 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid) unsigned long flags; domain = iommu_get_domain_for_dev_pasid(dev, pasid, 0); - if (WARN_ON_ONCE(!domain)) + if (WARN_ON_ONCE(IS_ERR_OR_NULL(domain))) goto out_tear_down; - /* - * The SVA implementation needs to handle its own stuffs like the mm - * notification. Before consolidating that code into iommu core, let - * the intel sva code handle it. - */ - if (domain_type_is_sva(dmar_domain)) { - intel_svm_remove_dev_pasid(dev, pasid); - goto out_tear_down; - } - dmar_domain = to_dmar_domain(domain); spin_lock_irqsave(&dmar_domain->lock, flags); list_for_each_entry(curr, &dmar_domain->dev_pasids, link_domain) { @@ -4730,6 +4720,10 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid) domain_detach_iommu(dmar_domain, iommu); kfree_rcu(dev_pasid, rcu); + if (list_empty(&to_dmar_domain(domain)->dev_pasids)) { + if (domain->notifier.ops) + mmu_notifier_unregister(&domain->notifier, domain->mm); + } out_tear_down: intel_pasid_tear_down_entry(iommu, dev, pasid, false); intel_drain_pasid_prq(dev, pasid); diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index b6dff0da9e8e..84e942a16666 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -860,7 +860,6 @@ int intel_svm_finish_prq(struct intel_iommu *iommu); int intel_svm_page_response(struct device *dev, struct iommu_fault_event *evt, struct iommu_page_response *msg); struct iommu_domain *intel_svm_domain_alloc(void); -void intel_svm_remove_dev_pasid(struct device *dev, ioasid_t pasid); void intel_drain_pasid_prq(struct device *dev, u32 pasid); #else static inline void intel_svm_check(struct intel_iommu *iommu) {} @@ -870,9 +869,6 @@ static inline struct iommu_domain *intel_svm_domain_alloc(void) return NULL; } -static inline void intel_svm_remove_dev_pasid(struct device *dev, ioasid_t pasid) -{ -} #endif #ifdef CONFIG_INTEL_IOMMU_DEBUGFS diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c index fd61fbf7593a..7f98c8acd04f 100644 --- a/drivers/iommu/intel/svm.c +++ b/drivers/iommu/intel/svm.c @@ -27,23 +27,6 @@ static irqreturn_t prq_event_thread(int irq, void *d); -static struct dev_pasid_info * -domain_lookup_dev_pasid_info_by_dev(struct dmar_domain *domain, struct device *dev) -{ - struct dev_pasid_info *dev_pasid = NULL, *t; - - rcu_read_lock(); - list_for_each_entry_rcu(t, &domain->dev_pasids, link_domain) { - if (t->dev == dev) { - dev_pasid = t; - break; - } - } - rcu_read_unlock(); - - return dev_pasid; -} - int intel_svm_enable_prq(struct intel_iommu *iommu) { struct iopf_queue *iopfq; @@ -301,28 +284,6 @@ static int intel_svm_set_dev_pasid(struct iommu_domain *domain, return ret; } -void intel_svm_remove_dev_pasid(struct device *dev, u32 pasid) -{ - struct iommu_domain *domain; - struct dev_pasid_info *dev_pasid; - - domain = iommu_get_domain_for_dev_pasid(dev, pasid, - IOMMU_DOMAIN_SVA); - if (WARN_ON_ONCE(IS_ERR_OR_NULL(domain))) - return; - - dev_pasid = domain_lookup_dev_pasid_info_by_dev(to_dmar_domain(domain), dev); - if (dev_pasid) { - list_del_rcu(&dev_pasid->link_domain); - kfree_rcu(dev_pasid, rcu); - - if (list_empty(&to_dmar_domain(domain)->dev_pasids)) { - if (domain->notifier.ops) - mmu_notifier_unregister(&domain->notifier, domain->mm); - } - } -} - /* Page request queue descriptor */ struct page_req_dsc { union { -- 2.39.3