# 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
|