diff options
author | Lu Baolu <baolu.lu@linux.intel.com> | 2018-07-14 03:46:56 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2018-07-20 08:44:24 -0400 |
commit | af39507305fb83a5d3c475c2851f4d59545d8a18 (patch) | |
tree | 09365a0dd4a8d1b936e28e1322087eb3568e3dbf /drivers | |
parent | 51261aac51a05c791ef880a100ac2ceed201ef72 (diff) |
iommu/vt-d: Apply global PASID in SVA
This patch applies the global pasid name space in the shared
virtual address (SVA) implementation.
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Liu Yi L <yi.l.liu@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Liu Yi L <yi.l.liu@intel.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/iommu/intel-svm.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index 36cc1d1b8afc..56e65d0b1871 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <asm/page.h> | 27 | #include <asm/page.h> |
28 | 28 | ||
29 | #include "intel-pasid.h" | ||
30 | |||
29 | #define PASID_ENTRY_P BIT_ULL(0) | 31 | #define PASID_ENTRY_P BIT_ULL(0) |
30 | #define PASID_ENTRY_FLPM_5LP BIT_ULL(9) | 32 | #define PASID_ENTRY_FLPM_5LP BIT_ULL(9) |
31 | #define PASID_ENTRY_SRE BIT_ULL(11) | 33 | #define PASID_ENTRY_SRE BIT_ULL(11) |
@@ -85,8 +87,6 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu) | |||
85 | iommu->name); | 87 | iommu->name); |
86 | } | 88 | } |
87 | 89 | ||
88 | idr_init(&iommu->pasid_idr); | ||
89 | |||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
@@ -102,7 +102,7 @@ int intel_svm_free_pasid_tables(struct intel_iommu *iommu) | |||
102 | free_pages((unsigned long)iommu->pasid_state_table, order); | 102 | free_pages((unsigned long)iommu->pasid_state_table, order); |
103 | iommu->pasid_state_table = NULL; | 103 | iommu->pasid_state_table = NULL; |
104 | } | 104 | } |
105 | idr_destroy(&iommu->pasid_idr); | 105 | |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | 108 | ||
@@ -392,9 +392,9 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ | |||
392 | pasid_max = iommu->pasid_max; | 392 | pasid_max = iommu->pasid_max; |
393 | 393 | ||
394 | /* Do not use PASID 0 in caching mode (virtualised IOMMU) */ | 394 | /* Do not use PASID 0 in caching mode (virtualised IOMMU) */ |
395 | ret = idr_alloc(&iommu->pasid_idr, svm, | 395 | ret = intel_pasid_alloc_id(svm, |
396 | !!cap_caching_mode(iommu->cap), | 396 | !!cap_caching_mode(iommu->cap), |
397 | pasid_max - 1, GFP_KERNEL); | 397 | pasid_max - 1, GFP_KERNEL); |
398 | if (ret < 0) { | 398 | if (ret < 0) { |
399 | kfree(svm); | 399 | kfree(svm); |
400 | kfree(sdev); | 400 | kfree(sdev); |
@@ -410,7 +410,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ | |||
410 | if (mm) { | 410 | if (mm) { |
411 | ret = mmu_notifier_register(&svm->notifier, mm); | 411 | ret = mmu_notifier_register(&svm->notifier, mm); |
412 | if (ret) { | 412 | if (ret) { |
413 | idr_remove(&svm->iommu->pasid_idr, svm->pasid); | 413 | intel_pasid_free_id(svm->pasid); |
414 | kfree(svm); | 414 | kfree(svm); |
415 | kfree(sdev); | 415 | kfree(sdev); |
416 | goto out; | 416 | goto out; |
@@ -460,7 +460,7 @@ int intel_svm_unbind_mm(struct device *dev, int pasid) | |||
460 | if (!iommu || !iommu->pasid_table) | 460 | if (!iommu || !iommu->pasid_table) |
461 | goto out; | 461 | goto out; |
462 | 462 | ||
463 | svm = idr_find(&iommu->pasid_idr, pasid); | 463 | svm = intel_pasid_lookup_id(pasid); |
464 | if (!svm) | 464 | if (!svm) |
465 | goto out; | 465 | goto out; |
466 | 466 | ||
@@ -485,7 +485,7 @@ int intel_svm_unbind_mm(struct device *dev, int pasid) | |||
485 | svm->iommu->pasid_table[svm->pasid].val = 0; | 485 | svm->iommu->pasid_table[svm->pasid].val = 0; |
486 | wmb(); | 486 | wmb(); |
487 | 487 | ||
488 | idr_remove(&svm->iommu->pasid_idr, svm->pasid); | 488 | intel_pasid_free_id(svm->pasid); |
489 | if (svm->mm) | 489 | if (svm->mm) |
490 | mmu_notifier_unregister(&svm->notifier, svm->mm); | 490 | mmu_notifier_unregister(&svm->notifier, svm->mm); |
491 | 491 | ||
@@ -520,7 +520,7 @@ int intel_svm_is_pasid_valid(struct device *dev, int pasid) | |||
520 | if (!iommu || !iommu->pasid_table) | 520 | if (!iommu || !iommu->pasid_table) |
521 | goto out; | 521 | goto out; |
522 | 522 | ||
523 | svm = idr_find(&iommu->pasid_idr, pasid); | 523 | svm = intel_pasid_lookup_id(pasid); |
524 | if (!svm) | 524 | if (!svm) |
525 | goto out; | 525 | goto out; |
526 | 526 | ||
@@ -618,7 +618,7 @@ static irqreturn_t prq_event_thread(int irq, void *d) | |||
618 | 618 | ||
619 | if (!svm || svm->pasid != req->pasid) { | 619 | if (!svm || svm->pasid != req->pasid) { |
620 | rcu_read_lock(); | 620 | rcu_read_lock(); |
621 | svm = idr_find(&iommu->pasid_idr, req->pasid); | 621 | svm = intel_pasid_lookup_id(req->pasid); |
622 | /* It *can't* go away, because the driver is not permitted | 622 | /* It *can't* go away, because the driver is not permitted |
623 | * to unbind the mm while any page faults are outstanding. | 623 | * to unbind the mm while any page faults are outstanding. |
624 | * So we only need RCU to protect the internal idr code. */ | 624 | * So we only need RCU to protect the internal idr code. */ |