aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-01-06 13:49:36 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-01-06 13:49:36 -0500
commit65cdc405b37a0f43af9c0fb6cf011304b3959ef8 (patch)
tree4becabf9b9ccf4695c0ea3d452d99b10cca5ade6
parent7397e1e838228a0957043613c265a611e09c05f3 (diff)
parent432abf68a79332282329286d190e21fe3ac02a31 (diff)
Merge tag 'iommu-fixes-v4.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull IOMMU fixes from Joerg Roedel: "Three fixes queued up: - fix an issue with command buffer overflow handling in the AMD IOMMU driver - add an additional context entry flush to the Intel VT-d driver to make sure any old context entry from kdump copying is flushed out of the cache - correct the encoding of the PASID table size in the Intel VT-d driver" * tag 'iommu-fixes-v4.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/amd: Fix the left value check of cmd buffer iommu/vt-d: Fix pasid table size encoding iommu/vt-d: Flush old iommu caches for kdump when the device gets context mapped
-rw-r--r--drivers/iommu/amd_iommu.c2
-rw-r--r--drivers/iommu/intel-iommu.c42
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)
5208static 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
5188int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev) 5226int 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