[xen-unstable] vtd: Fix pagetable teardown on domain detsruction.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen-unstable] vtd: Fix pagetable teardown on domain detsruction.

Xen patchbot-unstable
# HG changeset patch
# User Keir Fraser <[hidden email]>
# Date 1212397459 -3600
# Node ID 0216f0d07efed1bebab5b742e72756236363d8cc
# Parent  73a1daa9715f0a530ad76ab022e53df27f6856a6
vtd: Fix pagetable teardown on domain detsruction.
Signed-off-by: Xiaowei Yang <[hidden email]>
---
 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
[hidden email]
http://lists.xensource.com/xen-changelog