Skip to content

Commit

Permalink
intel-iommu: Avoid global flushes with caching mode.
Browse files Browse the repository at this point in the history
While it may be efficient on real hardware, emulation of global
invalidations is very expensive as all shadow entries must be examined.
This patch changes the behaviour when caching mode is enabled (which is
the case when IOMMU emulation takes place). In this case, page specific
invalidation is used instead.

Signed-off-by: Nadav Amit <[email protected]>
Signed-off-by: David Woodhouse <[email protected]>
  • Loading branch information
anadav authored and David Woodhouse committed Apr 9, 2010
1 parent 8265363 commit 78d5f0f
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions drivers/pci/intel-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2647,15 +2647,24 @@ static void flush_unmaps(void)
if (!deferred_flush[i].next)
continue;

iommu->flush.flush_iotlb(iommu, 0, 0, 0,
/* In caching mode, global flushes turn emulation expensive */
if (!cap_caching_mode(iommu->cap))
iommu->flush.flush_iotlb(iommu, 0, 0, 0,
DMA_TLB_GLOBAL_FLUSH);
for (j = 0; j < deferred_flush[i].next; j++) {
unsigned long mask;
struct iova *iova = deferred_flush[i].iova[j];

mask = ilog2(mm_to_dma_pfn(iova->pfn_hi - iova->pfn_lo + 1));
iommu_flush_dev_iotlb(deferred_flush[i].domain[j],
(uint64_t)iova->pfn_lo << PAGE_SHIFT, mask);
struct dmar_domain *domain = deferred_flush[i].domain[j];

/* On real hardware multiple invalidations are expensive */
if (cap_caching_mode(iommu->cap))
iommu_flush_iotlb_psi(iommu, domain->id,
iova->pfn_lo, iova->pfn_hi - iova->pfn_lo + 1, 0);
else {
mask = ilog2(mm_to_dma_pfn(iova->pfn_hi - iova->pfn_lo + 1));
iommu_flush_dev_iotlb(deferred_flush[i].domain[j],
(uint64_t)iova->pfn_lo << PAGE_SHIFT, mask);
}
__free_iova(&deferred_flush[i].domain[j]->iovad, iova);
}
deferred_flush[i].next = 0;
Expand Down

0 comments on commit 78d5f0f

Please sign in to comment.