ia64/xen-unstable
changeset 17724:5590509941b1
Fix iommu_unmap_page for VT-d
Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com>
Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Sat May 24 09:27:48 2008 +0100 (2008-05-24) |
parents | 572701272661 |
children | 36bbcc6baadf |
files | xen/drivers/passthrough/vtd/iommu.c |
line diff
1.1 --- a/xen/drivers/passthrough/vtd/iommu.c Sat May 24 09:25:04 2008 +0100 1.2 +++ b/xen/drivers/passthrough/vtd/iommu.c Sat May 24 09:27:48 2008 +0100 1.3 @@ -1518,6 +1518,8 @@ int intel_iommu_unmap_page(struct domain 1.4 { 1.5 struct acpi_drhd_unit *drhd; 1.6 struct iommu *iommu; 1.7 + struct dma_pte *page = NULL, *pte = NULL; 1.8 + u64 pg_maddr; 1.9 1.10 drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list); 1.11 iommu = drhd->iommu; 1.12 @@ -1528,7 +1530,24 @@ int intel_iommu_unmap_page(struct domain 1.13 return 0; 1.14 #endif 1.15 1.16 - dma_pte_clear_one(d, (paddr_t)gfn << PAGE_SHIFT_4K); 1.17 + pg_maddr = addr_to_dma_page_maddr(d, (paddr_t)gfn << PAGE_SHIFT_4K); 1.18 + if ( pg_maddr == 0 ) 1.19 + return -ENOMEM; 1.20 + page = (struct dma_pte *)map_vtd_domain_page(pg_maddr); 1.21 + pte = page + (gfn & LEVEL_MASK); 1.22 + dma_clear_pte(*pte); 1.23 + iommu_flush_cache_entry(drhd->iommu, pte); 1.24 + unmap_vtd_domain_page(page); 1.25 + 1.26 + for_each_drhd_unit ( drhd ) 1.27 + { 1.28 + iommu = drhd->iommu; 1.29 + if ( cap_caching_mode(iommu->cap) ) 1.30 + iommu_flush_iotlb_psi(iommu, domain_iommu_domid(d), 1.31 + (paddr_t)gfn << PAGE_SHIFT_4K, 1, 0); 1.32 + else if ( cap_rwbf(iommu->cap) ) 1.33 + iommu_flush_write_buffer(iommu); 1.34 + } 1.35 1.36 return 0; 1.37 }