Skip to content

Commit c4d27ff

Browse files
LuBaolujoergroedel
authored andcommitted
iommu/vt-d: Add cache tag invalidation helpers
Add several helpers to invalidate the caches after mappings in the affected domain are changed. - cache_tag_flush_range() invalidates a range of caches after mappings within this range are changed. It uses the page-selective cache invalidation methods. - cache_tag_flush_all() invalidates all caches tagged by a domain ID. It uses the domain-selective cache invalidation methods. - cache_tag_flush_range_np() invalidates a range of caches when new mappings are created in the domain and the corresponding page table entries change from non-present to present. Signed-off-by: Lu Baolu <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 3b1d9e2 commit c4d27ff

File tree

3 files changed

+209
-12
lines changed

3 files changed

+209
-12
lines changed

drivers/iommu/intel/cache.c

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/dmar.h>
1313
#include <linux/iommu.h>
1414
#include <linux/memory.h>
15+
#include <linux/pci.h>
1516
#include <linux/spinlock.h>
1617

1718
#include "iommu.h"
@@ -212,3 +213,197 @@ void cache_tag_unassign_domain(struct dmar_domain *domain,
212213
if (domain->domain.type == IOMMU_DOMAIN_NESTED)
213214
__cache_tag_unassign_parent_domain(domain->s2_domain, did, dev, pasid);
214215
}
216+
217+
static unsigned long calculate_psi_aligned_address(unsigned long start,
218+
unsigned long end,
219+
unsigned long *_pages,
220+
unsigned long *_mask)
221+
{
222+
unsigned long pages = aligned_nrpages(start, end - start + 1);
223+
unsigned long aligned_pages = __roundup_pow_of_two(pages);
224+
unsigned long bitmask = aligned_pages - 1;
225+
unsigned long mask = ilog2(aligned_pages);
226+
unsigned long pfn = IOVA_PFN(start);
227+
228+
/*
229+
* PSI masks the low order bits of the base address. If the
230+
* address isn't aligned to the mask, then compute a mask value
231+
* needed to ensure the target range is flushed.
232+
*/
233+
if (unlikely(bitmask & pfn)) {
234+
unsigned long end_pfn = pfn + pages - 1, shared_bits;
235+
236+
/*
237+
* Since end_pfn <= pfn + bitmask, the only way bits
238+
* higher than bitmask can differ in pfn and end_pfn is
239+
* by carrying. This means after masking out bitmask,
240+
* high bits starting with the first set bit in
241+
* shared_bits are all equal in both pfn and end_pfn.
242+
*/
243+
shared_bits = ~(pfn ^ end_pfn) & ~bitmask;
244+
mask = shared_bits ? __ffs(shared_bits) : BITS_PER_LONG;
245+
}
246+
247+
*_pages = aligned_pages;
248+
*_mask = mask;
249+
250+
return ALIGN_DOWN(start, VTD_PAGE_SIZE << mask);
251+
}
252+
253+
/*
254+
* Invalidates a range of IOVA from @start (inclusive) to @end (inclusive)
255+
* when the memory mappings in the target domain have been modified.
256+
*/
257+
void cache_tag_flush_range(struct dmar_domain *domain, unsigned long start,
258+
unsigned long end, int ih)
259+
{
260+
unsigned long pages, mask, addr;
261+
struct cache_tag *tag;
262+
unsigned long flags;
263+
264+
addr = calculate_psi_aligned_address(start, end, &pages, &mask);
265+
266+
spin_lock_irqsave(&domain->cache_lock, flags);
267+
list_for_each_entry(tag, &domain->cache_tags, node) {
268+
struct intel_iommu *iommu = tag->iommu;
269+
struct device_domain_info *info;
270+
u16 sid;
271+
272+
switch (tag->type) {
273+
case CACHE_TAG_IOTLB:
274+
case CACHE_TAG_NESTING_IOTLB:
275+
if (domain->use_first_level) {
276+
qi_flush_piotlb(iommu, tag->domain_id,
277+
tag->pasid, addr, pages, ih);
278+
} else {
279+
/*
280+
* Fallback to domain selective flush if no
281+
* PSI support or the size is too big.
282+
*/
283+
if (!cap_pgsel_inv(iommu->cap) ||
284+
mask > cap_max_amask_val(iommu->cap))
285+
iommu->flush.flush_iotlb(iommu, tag->domain_id,
286+
0, 0, DMA_TLB_DSI_FLUSH);
287+
else
288+
iommu->flush.flush_iotlb(iommu, tag->domain_id,
289+
addr | ih, mask,
290+
DMA_TLB_PSI_FLUSH);
291+
}
292+
break;
293+
case CACHE_TAG_NESTING_DEVTLB:
294+
/*
295+
* Address translation cache in device side caches the
296+
* result of nested translation. There is no easy way
297+
* to identify the exact set of nested translations
298+
* affected by a change in S2. So just flush the entire
299+
* device cache.
300+
*/
301+
addr = 0;
302+
mask = MAX_AGAW_PFN_WIDTH;
303+
fallthrough;
304+
case CACHE_TAG_DEVTLB:
305+
info = dev_iommu_priv_get(tag->dev);
306+
sid = PCI_DEVID(info->bus, info->devfn);
307+
308+
if (tag->pasid == IOMMU_NO_PASID)
309+
qi_flush_dev_iotlb(iommu, sid, info->pfsid,
310+
info->ats_qdep, addr, mask);
311+
else
312+
qi_flush_dev_iotlb_pasid(iommu, sid, info->pfsid,
313+
tag->pasid, info->ats_qdep,
314+
addr, mask);
315+
316+
quirk_extra_dev_tlb_flush(info, addr, mask, tag->pasid, info->ats_qdep);
317+
break;
318+
}
319+
}
320+
spin_unlock_irqrestore(&domain->cache_lock, flags);
321+
}
322+
323+
/*
324+
* Invalidates all ranges of IOVA when the memory mappings in the target
325+
* domain have been modified.
326+
*/
327+
void cache_tag_flush_all(struct dmar_domain *domain)
328+
{
329+
struct cache_tag *tag;
330+
unsigned long flags;
331+
332+
spin_lock_irqsave(&domain->cache_lock, flags);
333+
list_for_each_entry(tag, &domain->cache_tags, node) {
334+
struct intel_iommu *iommu = tag->iommu;
335+
struct device_domain_info *info;
336+
u16 sid;
337+
338+
switch (tag->type) {
339+
case CACHE_TAG_IOTLB:
340+
case CACHE_TAG_NESTING_IOTLB:
341+
if (domain->use_first_level)
342+
qi_flush_piotlb(iommu, tag->domain_id,
343+
tag->pasid, 0, -1, 0);
344+
else
345+
iommu->flush.flush_iotlb(iommu, tag->domain_id,
346+
0, 0, DMA_TLB_DSI_FLUSH);
347+
break;
348+
case CACHE_TAG_DEVTLB:
349+
case CACHE_TAG_NESTING_DEVTLB:
350+
info = dev_iommu_priv_get(tag->dev);
351+
sid = PCI_DEVID(info->bus, info->devfn);
352+
353+
qi_flush_dev_iotlb(iommu, sid, info->pfsid, info->ats_qdep,
354+
0, MAX_AGAW_PFN_WIDTH);
355+
quirk_extra_dev_tlb_flush(info, 0, MAX_AGAW_PFN_WIDTH,
356+
IOMMU_NO_PASID, info->ats_qdep);
357+
break;
358+
}
359+
}
360+
spin_unlock_irqrestore(&domain->cache_lock, flags);
361+
}
362+
363+
/*
364+
* Invalidate a range of IOVA when new mappings are created in the target
365+
* domain.
366+
*
367+
* - VT-d spec, Section 6.1 Caching Mode: When the CM field is reported as
368+
* Set, any software updates to remapping structures other than first-
369+
* stage mapping requires explicit invalidation of the caches.
370+
* - VT-d spec, Section 6.8 Write Buffer Flushing: For hardware that requires
371+
* write buffer flushing, software must explicitly perform write-buffer
372+
* flushing, if cache invalidation is not required.
373+
*/
374+
void cache_tag_flush_range_np(struct dmar_domain *domain, unsigned long start,
375+
unsigned long end)
376+
{
377+
unsigned long pages, mask, addr;
378+
struct cache_tag *tag;
379+
unsigned long flags;
380+
381+
addr = calculate_psi_aligned_address(start, end, &pages, &mask);
382+
383+
spin_lock_irqsave(&domain->cache_lock, flags);
384+
list_for_each_entry(tag, &domain->cache_tags, node) {
385+
struct intel_iommu *iommu = tag->iommu;
386+
387+
if (!cap_caching_mode(iommu->cap) || domain->use_first_level) {
388+
iommu_flush_write_buffer(iommu);
389+
continue;
390+
}
391+
392+
if (tag->type == CACHE_TAG_IOTLB ||
393+
tag->type == CACHE_TAG_NESTING_IOTLB) {
394+
/*
395+
* Fallback to domain selective flush if no
396+
* PSI support or the size is too big.
397+
*/
398+
if (!cap_pgsel_inv(iommu->cap) ||
399+
mask > cap_max_amask_val(iommu->cap))
400+
iommu->flush.flush_iotlb(iommu, tag->domain_id,
401+
0, 0, DMA_TLB_DSI_FLUSH);
402+
else
403+
iommu->flush.flush_iotlb(iommu, tag->domain_id,
404+
addr, mask,
405+
DMA_TLB_PSI_FLUSH);
406+
}
407+
}
408+
spin_unlock_irqrestore(&domain->cache_lock, flags);
409+
}

drivers/iommu/intel/iommu.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,6 @@
5454
__DOMAIN_MAX_PFN(gaw), (unsigned long)-1))
5555
#define DOMAIN_MAX_ADDR(gaw) (((uint64_t)__DOMAIN_MAX_PFN(gaw)) << VTD_PAGE_SHIFT)
5656

57-
/* IO virtual address start page frame number */
58-
#define IOVA_START_PFN (1)
59-
60-
#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
61-
6257
static void __init check_tylersburg_isoch(void);
6358
static int rwbf_quirk;
6459

@@ -1992,13 +1987,6 @@ domain_context_mapping(struct dmar_domain *domain, struct device *dev)
19921987
domain_context_mapping_cb, domain);
19931988
}
19941989

1995-
/* Returns a number of VTD pages, but aligned to MM page size */
1996-
static unsigned long aligned_nrpages(unsigned long host_addr, size_t size)
1997-
{
1998-
host_addr &= ~PAGE_MASK;
1999-
return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2000-
}
2001-
20021990
/* Return largest possible superpage level for a given mapping */
20031991
static int hardware_largepage_caps(struct dmar_domain *domain, unsigned long iov_pfn,
20041992
unsigned long phy_pfn, unsigned long pages)

drivers/iommu/intel/iommu.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#define VTD_PAGE_MASK (((u64)-1) << VTD_PAGE_SHIFT)
3636
#define VTD_PAGE_ALIGN(addr) (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK)
3737

38+
#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
39+
3840
#define VTD_STRIDE_SHIFT (9)
3941
#define VTD_STRIDE_MASK (((u64)-1) << VTD_STRIDE_SHIFT)
4042

@@ -1040,6 +1042,13 @@ static inline void context_set_sm_pre(struct context_entry *context)
10401042
context->lo |= BIT_ULL(4);
10411043
}
10421044

1045+
/* Returns a number of VTD pages, but aligned to MM page size */
1046+
static inline unsigned long aligned_nrpages(unsigned long host_addr, size_t size)
1047+
{
1048+
host_addr &= ~PAGE_MASK;
1049+
return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
1050+
}
1051+
10431052
/* Convert value to context PASID directory size field coding. */
10441053
#define context_pdts(pds) (((pds) & 0x7) << 9)
10451054

@@ -1121,6 +1130,11 @@ int cache_tag_assign_domain(struct dmar_domain *domain,
11211130
struct device *dev, ioasid_t pasid);
11221131
void cache_tag_unassign_domain(struct dmar_domain *domain,
11231132
struct device *dev, ioasid_t pasid);
1133+
void cache_tag_flush_range(struct dmar_domain *domain, unsigned long start,
1134+
unsigned long end, int ih);
1135+
void cache_tag_flush_all(struct dmar_domain *domain);
1136+
void cache_tag_flush_range_np(struct dmar_domain *domain, unsigned long start,
1137+
unsigned long end);
11241138

11251139
#ifdef CONFIG_INTEL_IOMMU_SVM
11261140
void intel_svm_check(struct intel_iommu *iommu);

0 commit comments

Comments
 (0)