hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/iommu/intel/pasid.c
....@@ -24,7 +24,6 @@
2424 /*
2525 * Intel IOMMU system wide PASID name space:
2626 */
27
-static DEFINE_SPINLOCK(pasid_lock);
2827 u32 intel_pasid_max_id = PASID_MAX;
2928
3029 int vcmd_alloc_pasid(struct intel_iommu *iommu, u32 *pasid)
....@@ -187,6 +186,9 @@
187186 attach_out:
188187 device_attach_pasid_table(info, pasid_table);
189188
189
+ if (!ecap_coherent(info->iommu->ecap))
190
+ clflush_cache_range(pasid_table->table, (1 << order) * PAGE_SIZE);
191
+
190192 return 0;
191193 }
192194
....@@ -259,19 +261,29 @@
259261 dir_index = pasid >> PASID_PDE_SHIFT;
260262 index = pasid & PASID_PTE_MASK;
261263
262
- spin_lock(&pasid_lock);
264
+retry:
263265 entries = get_pasid_table_from_pde(&dir[dir_index]);
264266 if (!entries) {
265267 entries = alloc_pgtable_page(info->iommu->node);
266
- if (!entries) {
267
- spin_unlock(&pasid_lock);
268
+ if (!entries)
268269 return NULL;
269
- }
270270
271
- WRITE_ONCE(dir[dir_index].val,
272
- (u64)virt_to_phys(entries) | PASID_PTE_PRESENT);
271
+ /*
272
+ * The pasid directory table entry won't be freed after
273
+ * allocation. No worry about the race with free and
274
+ * clear. However, this entry might be populated by others
275
+ * while we are preparing it. Use theirs with a retry.
276
+ */
277
+ if (cmpxchg64(&dir[dir_index].val, 0ULL,
278
+ (u64)virt_to_phys(entries) | PASID_PTE_PRESENT)) {
279
+ free_pgtable_page(entries);
280
+ goto retry;
281
+ }
282
+ if (!ecap_coherent(info->iommu->ecap)) {
283
+ clflush_cache_range(entries, VTD_PAGE_SIZE);
284
+ clflush_cache_range(&dir[dir_index].val, sizeof(*dir));
285
+ }
273286 }
274
- spin_unlock(&pasid_lock);
275287
276288 return &entries[index];
277289 }