diff options
| -rw-r--r-- | drivers/iommu/amd_iommu.c | 2 | ||||
| -rw-r--r-- | drivers/iommu/intel-iommu.c | 42 |
2 files changed, 42 insertions, 2 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 019e02707cd5..3ef0f42984f2 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
| @@ -1023,7 +1023,7 @@ again: | |||
| 1023 | next_tail = (tail + sizeof(*cmd)) % CMD_BUFFER_SIZE; | 1023 | next_tail = (tail + sizeof(*cmd)) % CMD_BUFFER_SIZE; |
| 1024 | left = (head - next_tail) % CMD_BUFFER_SIZE; | 1024 | left = (head - next_tail) % CMD_BUFFER_SIZE; |
| 1025 | 1025 | ||
| 1026 | if (left <= 2) { | 1026 | if (left <= 0x20) { |
| 1027 | struct iommu_cmd sync_cmd; | 1027 | struct iommu_cmd sync_cmd; |
| 1028 | int ret; | 1028 | int ret; |
| 1029 | 1029 | ||
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index c66c273dfd8a..8a185250ae5a 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
| @@ -2037,6 +2037,25 @@ static int domain_context_mapping_one(struct dmar_domain *domain, | |||
| 2037 | if (context_present(context)) | 2037 | if (context_present(context)) |
| 2038 | goto out_unlock; | 2038 | goto out_unlock; |
| 2039 | 2039 | ||
| 2040 | /* | ||
| 2041 | * For kdump cases, old valid entries may be cached due to the | ||
| 2042 | * in-flight DMA and copied pgtable, but there is no unmapping | ||
| 2043 | * behaviour for them, thus we need an explicit cache flush for | ||
| 2044 | * the newly-mapped device. For kdump, at this point, the device | ||
| 2045 | * is supposed to finish reset at its driver probe stage, so no | ||
| 2046 | * in-flight DMA will exist, and we don't need to worry anymore | ||
| 2047 | * hereafter. | ||
| 2048 | */ | ||
| 2049 | if (context_copied(context)) { | ||
| 2050 | u16 did_old = context_domain_id(context); | ||
| 2051 | |||
| 2052 | if (did_old >= 0 && did_old < cap_ndoms(iommu->cap)) | ||
| 2053 | iommu->flush.flush_context(iommu, did_old, | ||
| 2054 | (((u16)bus) << 8) | devfn, | ||
| 2055 | DMA_CCMD_MASK_NOBIT, | ||
| 2056 | DMA_CCMD_DEVICE_INVL); | ||
| 2057 | } | ||
| 2058 | |||
| 2040 | pgd = domain->pgd; | 2059 | pgd = domain->pgd; |
| 2041 | 2060 | ||
| 2042 | context_clear_entry(context); | 2061 | context_clear_entry(context); |
| @@ -5185,6 +5204,25 @@ static void intel_iommu_remove_device(struct device *dev) | |||
| 5185 | } | 5204 | } |
| 5186 | 5205 | ||
| 5187 | #ifdef CONFIG_INTEL_IOMMU_SVM | 5206 | #ifdef CONFIG_INTEL_IOMMU_SVM |
| 5207 | #define MAX_NR_PASID_BITS (20) | ||
| 5208 | static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu) | ||
| 5209 | { | ||
| 5210 | /* | ||
| 5211 | * Convert ecap_pss to extend context entry pts encoding, also | ||
| 5212 | * respect the soft pasid_max value set by the iommu. | ||
| 5213 | * - number of PASID bits = ecap_pss + 1 | ||
| 5214 | * - number of PASID table entries = 2^(pts + 5) | ||
| 5215 | * Therefore, pts = ecap_pss - 4 | ||
| 5216 | * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15 | ||
| 5217 | */ | ||
| 5218 | if (ecap_pss(iommu->ecap) < 5) | ||
| 5219 | return 0; | ||
| 5220 | |||
| 5221 | /* pasid_max is encoded as actual number of entries not the bits */ | ||
| 5222 | return find_first_bit((unsigned long *)&iommu->pasid_max, | ||
| 5223 | MAX_NR_PASID_BITS) - 5; | ||
| 5224 | } | ||
| 5225 | |||
| 5188 | int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev) | 5226 | int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev) |
| 5189 | { | 5227 | { |
| 5190 | struct device_domain_info *info; | 5228 | struct device_domain_info *info; |
| @@ -5217,7 +5255,9 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd | |||
| 5217 | 5255 | ||
| 5218 | if (!(ctx_lo & CONTEXT_PASIDE)) { | 5256 | if (!(ctx_lo & CONTEXT_PASIDE)) { |
| 5219 | context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table); | 5257 | context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table); |
| 5220 | context[1].lo = (u64)virt_to_phys(iommu->pasid_table) | ecap_pss(iommu->ecap); | 5258 | context[1].lo = (u64)virt_to_phys(iommu->pasid_table) | |
| 5259 | intel_iommu_get_pts(iommu); | ||
| 5260 | |||
| 5221 | wmb(); | 5261 | wmb(); |
| 5222 | /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both | 5262 | /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both |
| 5223 | * extended to permit requests-with-PASID if the PASIDE bit | 5263 | * extended to permit requests-with-PASID if the PASIDE bit |
