[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] vtd: Fix pagetable teardown on domain detsruction.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1212397459 -3600 # Node ID 0216f0d07efed1bebab5b742e72756236363d8cc # Parent 73a1daa9715f0a530ad76ab022e53df27f6856a6 vtd: Fix pagetable teardown on domain detsruction. Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx> --- xen/drivers/passthrough/vtd/iommu.c | 63 +++++++++++++----------------------- 1 files changed, 24 insertions(+), 39 deletions(-) diff -r 73a1daa9715f -r 0216f0d07efe xen/drivers/passthrough/vtd/iommu.c --- a/xen/drivers/passthrough/vtd/iommu.c Mon Jun 02 10:03:18 2008 +0100 +++ b/xen/drivers/passthrough/vtd/iommu.c Mon Jun 02 10:04:19 2008 +0100 @@ -587,50 +587,32 @@ static void dma_pte_clear_range(struct d } } -static void iommu_free_next_pagetable(u64 pt_maddr, unsigned long index, - int level) -{ - unsigned long next_index; - struct dma_pte *pt_vaddr, *pde; - int next_level; +static void iommu_free_pagetable(u64 pt_maddr, int level) +{ + int i; + struct dma_pte *pt_vaddr, *pte; + int next_level = level - 1; if ( pt_maddr == 0 ) return; pt_vaddr = (struct dma_pte *)map_vtd_domain_page(pt_maddr); - pde = &pt_vaddr[index]; - if ( dma_pte_addr(*pde) == 0 ) - goto out; - - next_level = level - 1; - if ( next_level > 1 ) - { - for ( next_index = 0; next_index < PTE_NUM; next_index++ ) - iommu_free_next_pagetable(pde->val, next_index, next_level); - } - - dma_clear_pte(*pde); - iommu_flush_cache_entry(pde); - free_pgtable_maddr(pde->val); - - out: + + for ( i = 0; i < PTE_NUM; i++ ) + { + pte = &pt_vaddr[i]; + if ( !dma_pte_present(*pte) ) + continue; + + if ( next_level >= 1 ) + iommu_free_pagetable(dma_pte_addr(*pte), next_level); + + dma_clear_pte(*pte); + iommu_flush_cache_entry(pte); + } + unmap_vtd_domain_page(pt_vaddr); -} - -/* free all VT-d page tables when shut down or destroy domain. */ -static void iommu_free_pagetable(struct domain *domain) -{ - struct hvm_iommu *hd = domain_hvm_iommu(domain); - int i, total_level = agaw_to_level(hd->agaw); - - if ( hd->pgd_maddr == 0 ) - return; - - for ( i = 0; i < PTE_NUM; i++ ) - iommu_free_next_pagetable(hd->pgd_maddr, i, total_level + 1); - - free_pgtable_maddr(hd->pgd_maddr); - hd->pgd_maddr = 0; + free_pgtable_maddr(pt_maddr); } static int iommu_set_root_entry(struct iommu *iommu) @@ -1456,11 +1438,14 @@ void return_devices_to_dom0(struct domai void iommu_domain_teardown(struct domain *d) { + struct hvm_iommu *hd = domain_hvm_iommu(d); + if ( list_empty(&acpi_drhd_units) ) return; - iommu_free_pagetable(d); return_devices_to_dom0(d); + iommu_free_pagetable(hd->pgd_maddr, agaw_to_level(hd->agaw)); + hd->pgd_maddr = 0; iommu_domid_release(d); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |