Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78d5f0f5 authored by Nadav Amit's avatar Nadav Amit Committed by David Woodhouse
Browse files

intel-iommu: Avoid global flushes with caching mode.



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: default avatarNadav Amit <nadav.amit@gmail.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 82653633
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -2647,15 +2647,24 @@ static void flush_unmaps(void)
		if (!deferred_flush[i].next)
			continue;

		/* 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];
			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;