@@ -258,6 +258,34 @@ static void nvidia_smmu_probe_finalize(struct arm_smmu_device *smmu, struct devi
258
258
dev_name (dev ), err );
259
259
}
260
260
261
+ static int nvidia_smmu_init_context (struct arm_smmu_domain * smmu_domain ,
262
+ struct io_pgtable_cfg * pgtbl_cfg ,
263
+ struct device * dev )
264
+ {
265
+ struct arm_smmu_device * smmu = smmu_domain -> smmu ;
266
+ const struct device_node * np = smmu -> dev -> of_node ;
267
+
268
+ /*
269
+ * Tegra194 and Tegra234 SoCs have the erratum that causes walk cache
270
+ * entries to not be invalidated correctly. The problem is that the walk
271
+ * cache index generated for IOVA is not same across translation and
272
+ * invalidation requests. This is leading to page faults when PMD entry
273
+ * is released during unmap and populated with new PTE table during
274
+ * subsequent map request. Disabling large page mappings avoids the
275
+ * release of PMD entry and avoid translations seeing stale PMD entry in
276
+ * walk cache.
277
+ * Fix this by limiting the page mappings to PAGE_SIZE on Tegra194 and
278
+ * Tegra234.
279
+ */
280
+ if (of_device_is_compatible (np , "nvidia,tegra234-smmu" ) ||
281
+ of_device_is_compatible (np , "nvidia,tegra194-smmu" )) {
282
+ smmu -> pgsize_bitmap = PAGE_SIZE ;
283
+ pgtbl_cfg -> pgsize_bitmap = smmu -> pgsize_bitmap ;
284
+ }
285
+
286
+ return 0 ;
287
+ }
288
+
261
289
static const struct arm_smmu_impl nvidia_smmu_impl = {
262
290
.read_reg = nvidia_smmu_read_reg ,
263
291
.write_reg = nvidia_smmu_write_reg ,
@@ -268,10 +296,12 @@ static const struct arm_smmu_impl nvidia_smmu_impl = {
268
296
.global_fault = nvidia_smmu_global_fault ,
269
297
.context_fault = nvidia_smmu_context_fault ,
270
298
.probe_finalize = nvidia_smmu_probe_finalize ,
299
+ .init_context = nvidia_smmu_init_context ,
271
300
};
272
301
273
302
static const struct arm_smmu_impl nvidia_smmu_single_impl = {
274
303
.probe_finalize = nvidia_smmu_probe_finalize ,
304
+ .init_context = nvidia_smmu_init_context ,
275
305
};
276
306
277
307
struct arm_smmu_device * nvidia_smmu_impl_init (struct arm_smmu_device * smmu )
0 commit comments