Patch Description: The patch is for Intel IOMMU driver. It forces IOMMU TLB
flush for the particular domain and return correct unmap size when
intel_iommu_unmap() is called
The patch is generated on Linux kernel version 3.6.11
--- linux/drivers/iommu/intel-iommu.c.orig 2013-09-01 10:10:14.723958000
-0700
+++ linux/drivers/iommu/intel-iommu.c 2013-09-01 18:22:58.497578000 -0700
@@ -4060,14 +4060,31 @@ static size_t intel_iommu_unmap(struct i
{
struct dmar_domain *dmar_domain = domain->priv;
int order;
+ struct intel_iommu *iommu;
+ unsigned long start_pfn, last_pfn;
+ unsigned int npages;
+ int iommu_id, num, ndomains;
- order = dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
- (iova + size - 1) >> VTD_PAGE_SHIFT);
+ start_pfn = iova >> VTD_PAGE_SHIFT;
+ last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
+ order = dma_pte_clear_range(dmar_domain, start_pfn, last_pfn);
+ last_pfn |= (1UL << order) - 1;
+ npages = last_pfn - start_pfn + 1;
+ for_each_set_bit(iommu_id, dmar_domain->iommu_bmp, g_num_of_iommus) {
+ iommu = g_iommus[iommu_id];
- if (dmar_domain->max_addr == iova + size)
+ /*
+ * find bit position of dmar_domain
+ */
+ ndomains = cap_ndoms(iommu->cap);
+ for_each_set_bit(num, iommu->domain_ids, ndomains)
+ if (iommu->domains[num] == dmar_domain)
+ iommu_flush_iotlb_psi(iommu, num,
+ start_pfn, npages, 0);
+ }
+ if (dmar_domain->max_addr <= iova + (npages << VTD_PAGE_SHIFT))
dmar_domain->max_addr = iova;
-
- return PAGE_SIZE << order;
+ return npages << VTD_PAGE_SHIFT;
}
static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Signed-off-by: Hari Shankar <[email protected]>
cc: [email protected]
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu