diff options
| author | David Woodhouse <David.Woodhouse@intel.com> | 2015-10-13 09:11:13 -0400 |
|---|---|---|
| committer | David Woodhouse <David.Woodhouse@intel.com> | 2015-10-15 08:22:35 -0400 |
| commit | 907fea3491d52063bb37b1f1ce0cf8a4ae70944c (patch) | |
| tree | 87bd60e81510676710fd1cedeb678c42e8d9704b | |
| parent | 2f26e0a9c9860db290d63e9d85c2c8c09813677f (diff) | |
iommu/vt-d: Implement deferred invalidate for SVM
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
| -rw-r--r-- | drivers/iommu/intel-iommu.c | 2 | ||||
| -rw-r--r-- | drivers/iommu/intel-svm.c | 9 | ||||
| -rw-r--r-- | include/linux/dma_remapping.h | 1 |
3 files changed, 12 insertions, 0 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 60b66d27e655..58ecd52af43b 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
| @@ -4981,6 +4981,8 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd | |||
| 4981 | ctx_lo |= CONTEXT_TT_PT_PASID << 2; | 4981 | ctx_lo |= CONTEXT_TT_PT_PASID << 2; |
| 4982 | } | 4982 | } |
| 4983 | ctx_lo |= CONTEXT_PASIDE; | 4983 | ctx_lo |= CONTEXT_PASIDE; |
| 4984 | if (iommu->pasid_state_table) | ||
| 4985 | ctx_lo |= CONTEXT_DINVE; | ||
| 4984 | context[0].lo = ctx_lo; | 4986 | context[0].lo = ctx_lo; |
| 4985 | wmb(); | 4987 | wmb(); |
| 4986 | iommu->flush.flush_context(iommu, sdev->did, sdev->sid, | 4988 | iommu->flush.flush_context(iommu, sdev->did, sdev->sid, |
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index 82d53e15b865..a64720b5bd34 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c | |||
| @@ -26,6 +26,10 @@ struct pasid_entry { | |||
| 26 | u64 val; | 26 | u64 val; |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | struct pasid_state_entry { | ||
| 30 | u64 val; | ||
| 31 | }; | ||
| 32 | |||
| 29 | int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu) | 33 | int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu) |
| 30 | { | 34 | { |
| 31 | struct page *pages; | 35 | struct page *pages; |
| @@ -127,6 +131,11 @@ static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address, | |||
| 127 | { | 131 | { |
| 128 | struct intel_svm_dev *sdev; | 132 | struct intel_svm_dev *sdev; |
| 129 | 133 | ||
| 134 | /* Try deferred invalidate if available */ | ||
| 135 | if (svm->iommu->pasid_state_table && | ||
| 136 | !cmpxchg64(&svm->iommu->pasid_state_table[svm->pasid].val, 0, 1ULL << 63)) | ||
| 137 | return; | ||
| 138 | |||
| 130 | rcu_read_lock(); | 139 | rcu_read_lock(); |
| 131 | list_for_each_entry_rcu(sdev, &svm->devs, list) | 140 | list_for_each_entry_rcu(sdev, &svm->devs, list) |
| 132 | intel_flush_svm_range_dev(svm, sdev, address, pages, ih); | 141 | intel_flush_svm_range_dev(svm, sdev, address, pages, ih); |
diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h index 0e114bfabeed..187c10299722 100644 --- a/include/linux/dma_remapping.h +++ b/include/linux/dma_remapping.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #define CONTEXT_TT_PT_PASID_DEV_IOTLB 5 | 25 | #define CONTEXT_TT_PT_PASID_DEV_IOTLB 5 |
| 26 | #define CONTEXT_TT_MASK (7ULL << 2) | 26 | #define CONTEXT_TT_MASK (7ULL << 2) |
| 27 | 27 | ||
| 28 | #define CONTEXT_DINVE (1ULL << 8) | ||
| 28 | #define CONTEXT_PRS (1ULL << 9) | 29 | #define CONTEXT_PRS (1ULL << 9) |
| 29 | #define CONTEXT_PASIDE (1ULL << 11) | 30 | #define CONTEXT_PASIDE (1ULL << 11) |
| 30 | 31 | ||
