diff options
-rw-r--r-- | drivers/iommu/intel-svm.c | 14 | ||||
-rw-r--r-- | include/linux/intel-iommu.h | 1 |
2 files changed, 11 insertions, 4 deletions
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index 2cc0aac93201..36cc1d1b8afc 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c | |||
@@ -298,6 +298,7 @@ static const struct mmu_notifier_ops intel_mmuops = { | |||
298 | }; | 298 | }; |
299 | 299 | ||
300 | static DEFINE_MUTEX(pasid_mutex); | 300 | static DEFINE_MUTEX(pasid_mutex); |
301 | static LIST_HEAD(global_svm_list); | ||
301 | 302 | ||
302 | int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ops *ops) | 303 | int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ops *ops) |
303 | { | 304 | { |
@@ -329,13 +330,13 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ | |||
329 | 330 | ||
330 | mutex_lock(&pasid_mutex); | 331 | mutex_lock(&pasid_mutex); |
331 | if (pasid && !(flags & SVM_FLAG_PRIVATE_PASID)) { | 332 | if (pasid && !(flags & SVM_FLAG_PRIVATE_PASID)) { |
332 | int i; | 333 | struct intel_svm *t; |
333 | 334 | ||
334 | idr_for_each_entry(&iommu->pasid_idr, svm, i) { | 335 | list_for_each_entry(t, &global_svm_list, list) { |
335 | if (svm->mm != mm || | 336 | if (t->mm != mm || (t->flags & SVM_FLAG_PRIVATE_PASID)) |
336 | (svm->flags & SVM_FLAG_PRIVATE_PASID)) | ||
337 | continue; | 337 | continue; |
338 | 338 | ||
339 | svm = t; | ||
339 | if (svm->pasid >= pasid_max) { | 340 | if (svm->pasid >= pasid_max) { |
340 | dev_warn(dev, | 341 | dev_warn(dev, |
341 | "Limited PASID width. Cannot use existing PASID %d\n", | 342 | "Limited PASID width. Cannot use existing PASID %d\n", |
@@ -404,6 +405,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ | |||
404 | svm->mm = mm; | 405 | svm->mm = mm; |
405 | svm->flags = flags; | 406 | svm->flags = flags; |
406 | INIT_LIST_HEAD_RCU(&svm->devs); | 407 | INIT_LIST_HEAD_RCU(&svm->devs); |
408 | INIT_LIST_HEAD(&svm->list); | ||
407 | ret = -ENOMEM; | 409 | ret = -ENOMEM; |
408 | if (mm) { | 410 | if (mm) { |
409 | ret = mmu_notifier_register(&svm->notifier, mm); | 411 | ret = mmu_notifier_register(&svm->notifier, mm); |
@@ -430,6 +432,8 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ | |||
430 | */ | 432 | */ |
431 | if (cap_caching_mode(iommu->cap)) | 433 | if (cap_caching_mode(iommu->cap)) |
432 | intel_flush_pasid_dev(svm, sdev, svm->pasid); | 434 | intel_flush_pasid_dev(svm, sdev, svm->pasid); |
435 | |||
436 | list_add_tail(&svm->list, &global_svm_list); | ||
433 | } | 437 | } |
434 | list_add_rcu(&sdev->list, &svm->devs); | 438 | list_add_rcu(&sdev->list, &svm->devs); |
435 | 439 | ||
@@ -485,6 +489,8 @@ int intel_svm_unbind_mm(struct device *dev, int pasid) | |||
485 | if (svm->mm) | 489 | if (svm->mm) |
486 | mmu_notifier_unregister(&svm->notifier, svm->mm); | 490 | mmu_notifier_unregister(&svm->notifier, svm->mm); |
487 | 491 | ||
492 | list_del(&svm->list); | ||
493 | |||
488 | /* We mandate that no page faults may be outstanding | 494 | /* We mandate that no page faults may be outstanding |
489 | * for the PASID when intel_svm_unbind_mm() is called. | 495 | * for the PASID when intel_svm_unbind_mm() is called. |
490 | * If that is not obeyed, subtle errors will happen. | 496 | * If that is not obeyed, subtle errors will happen. |
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 6692b40ca814..e1e193855581 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
@@ -487,6 +487,7 @@ struct intel_svm { | |||
487 | int flags; | 487 | int flags; |
488 | int pasid; | 488 | int pasid; |
489 | struct list_head devs; | 489 | struct list_head devs; |
490 | struct list_head list; | ||
490 | }; | 491 | }; |
491 | 492 | ||
492 | extern int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev); | 493 | extern int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev); |