diff options
| -rw-r--r-- | drivers/iommu/intel-iommu.c | 1 | ||||
| -rw-r--r-- | drivers/iommu/intel-svm.c | 45 | ||||
| -rw-r--r-- | include/linux/intel-iommu.h | 8 |
3 files changed, 0 insertions, 54 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index cec88df671a6..9043e1e9b2be 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
| @@ -1700,7 +1700,6 @@ static void free_dmar_iommu(struct intel_iommu *iommu) | |||
| 1700 | if (pasid_supported(iommu)) { | 1700 | if (pasid_supported(iommu)) { |
| 1701 | if (ecap_prs(iommu->ecap)) | 1701 | if (ecap_prs(iommu->ecap)) |
| 1702 | intel_svm_finish_prq(iommu); | 1702 | intel_svm_finish_prq(iommu); |
| 1703 | intel_svm_exit(iommu); | ||
| 1704 | } | 1703 | } |
| 1705 | #endif | 1704 | #endif |
| 1706 | } | 1705 | } |
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index 04d6bdb51404..5b2e3b2d593b 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c | |||
| @@ -31,15 +31,8 @@ | |||
| 31 | 31 | ||
| 32 | static irqreturn_t prq_event_thread(int irq, void *d); | 32 | static irqreturn_t prq_event_thread(int irq, void *d); |
| 33 | 33 | ||
| 34 | struct pasid_state_entry { | ||
| 35 | u64 val; | ||
| 36 | }; | ||
| 37 | |||
| 38 | int intel_svm_init(struct intel_iommu *iommu) | 34 | int intel_svm_init(struct intel_iommu *iommu) |
| 39 | { | 35 | { |
| 40 | struct page *pages; | ||
| 41 | int order; | ||
| 42 | |||
| 43 | if (cpu_feature_enabled(X86_FEATURE_GBPAGES) && | 36 | if (cpu_feature_enabled(X86_FEATURE_GBPAGES) && |
| 44 | !cap_fl1gp_support(iommu->cap)) | 37 | !cap_fl1gp_support(iommu->cap)) |
| 45 | return -EINVAL; | 38 | return -EINVAL; |
| @@ -48,39 +41,6 @@ int intel_svm_init(struct intel_iommu *iommu) | |||
| 48 | !cap_5lp_support(iommu->cap)) | 41 | !cap_5lp_support(iommu->cap)) |
| 49 | return -EINVAL; | 42 | return -EINVAL; |
| 50 | 43 | ||
| 51 | /* Start at 2 because it's defined as 2^(1+PSS) */ | ||
| 52 | iommu->pasid_max = 2 << ecap_pss(iommu->ecap); | ||
| 53 | |||
| 54 | /* Eventually I'm promised we will get a multi-level PASID table | ||
| 55 | * and it won't have to be physically contiguous. Until then, | ||
| 56 | * limit the size because 8MiB contiguous allocations can be hard | ||
| 57 | * to come by. The limit of 0x20000, which is 1MiB for each of | ||
| 58 | * the PASID and PASID-state tables, is somewhat arbitrary. */ | ||
| 59 | if (iommu->pasid_max > 0x20000) | ||
| 60 | iommu->pasid_max = 0x20000; | ||
| 61 | |||
| 62 | order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max); | ||
| 63 | if (ecap_dis(iommu->ecap)) { | ||
| 64 | pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); | ||
| 65 | if (pages) | ||
| 66 | iommu->pasid_state_table = page_address(pages); | ||
| 67 | else | ||
| 68 | pr_warn("IOMMU: %s: Failed to allocate PASID state table\n", | ||
| 69 | iommu->name); | ||
| 70 | } | ||
| 71 | |||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | int intel_svm_exit(struct intel_iommu *iommu) | ||
| 76 | { | ||
| 77 | int order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max); | ||
| 78 | |||
| 79 | if (iommu->pasid_state_table) { | ||
| 80 | free_pages((unsigned long)iommu->pasid_state_table, order); | ||
| 81 | iommu->pasid_state_table = NULL; | ||
| 82 | } | ||
| 83 | |||
| 84 | return 0; | 44 | return 0; |
| 85 | } | 45 | } |
| 86 | 46 | ||
| @@ -214,11 +174,6 @@ static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address, | |||
| 214 | { | 174 | { |
| 215 | struct intel_svm_dev *sdev; | 175 | struct intel_svm_dev *sdev; |
| 216 | 176 | ||
| 217 | /* Try deferred invalidate if available */ | ||
| 218 | if (svm->iommu->pasid_state_table && | ||
| 219 | !cmpxchg64(&svm->iommu->pasid_state_table[svm->pasid].val, 0, 1ULL << 63)) | ||
| 220 | return; | ||
| 221 | |||
| 222 | rcu_read_lock(); | 177 | rcu_read_lock(); |
| 223 | list_for_each_entry_rcu(sdev, &svm->devs, list) | 178 | list_for_each_entry_rcu(sdev, &svm->devs, list) |
| 224 | intel_flush_svm_range_dev(svm, sdev, address, pages, ih, gl); | 179 | intel_flush_svm_range_dev(svm, sdev, address, pages, ih, gl); |
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index cfcf9c1e1872..0605f3bf6e79 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
| @@ -541,15 +541,8 @@ struct intel_iommu { | |||
| 541 | struct iommu_flush flush; | 541 | struct iommu_flush flush; |
| 542 | #endif | 542 | #endif |
| 543 | #ifdef CONFIG_INTEL_IOMMU_SVM | 543 | #ifdef CONFIG_INTEL_IOMMU_SVM |
| 544 | /* These are large and need to be contiguous, so we allocate just | ||
| 545 | * one for now. We'll maybe want to rethink that if we truly give | ||
| 546 | * devices away to userspace processes (e.g. for DPDK) and don't | ||
| 547 | * want to trust that userspace will use *only* the PASID it was | ||
| 548 | * told to. But while it's all driver-arbitrated, we're fine. */ | ||
| 549 | struct pasid_state_entry *pasid_state_table; | ||
| 550 | struct page_req_dsc *prq; | 544 | struct page_req_dsc *prq; |
| 551 | unsigned char prq_name[16]; /* Name for PRQ interrupt */ | 545 | unsigned char prq_name[16]; /* Name for PRQ interrupt */ |
| 552 | u32 pasid_max; | ||
| 553 | #endif | 546 | #endif |
| 554 | struct q_inval *qi; /* Queued invalidation info */ | 547 | struct q_inval *qi; /* Queued invalidation info */ |
| 555 | u32 *iommu_state; /* Store iommu states between suspend and resume.*/ | 548 | u32 *iommu_state; /* Store iommu states between suspend and resume.*/ |
| @@ -663,7 +656,6 @@ void iommu_flush_write_buffer(struct intel_iommu *iommu); | |||
| 663 | 656 | ||
| 664 | #ifdef CONFIG_INTEL_IOMMU_SVM | 657 | #ifdef CONFIG_INTEL_IOMMU_SVM |
| 665 | int intel_svm_init(struct intel_iommu *iommu); | 658 | int intel_svm_init(struct intel_iommu *iommu); |
| 666 | int intel_svm_exit(struct intel_iommu *iommu); | ||
| 667 | extern int intel_svm_enable_prq(struct intel_iommu *iommu); | 659 | extern int intel_svm_enable_prq(struct intel_iommu *iommu); |
| 668 | extern int intel_svm_finish_prq(struct intel_iommu *iommu); | 660 | extern int intel_svm_finish_prq(struct intel_iommu *iommu); |
| 669 | 661 | ||
