WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] VT-d: Fix free VT-d page table issue

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] VT-d: Fix free VT-d page table issue
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 07 May 2008 09:40:12 -0700
Delivery-date: Wed, 07 May 2008 09:40:19 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1210148380 -3600
# Node ID fb58da5167497ce8752f99673149911909f0f269
# Parent  9d2a45d4b6c6ecf6d99f01dd035326d2215c548c
VT-d: Fix free VT-d page table issue

This patch frees VT-d page tables from pgd, rather than free them
according to a guest address range.

This fixes [Bug 1244] Poweroff/Destroying HVM guest causes HV
crash. http://bugzilla.xensource.com/bugzilla/show_bug.cgi?id=1244.

Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
 xen/drivers/passthrough/vtd/iommu.c |   62 +++++++++++++++++++++++++++++++-----
 xen/drivers/passthrough/vtd/iommu.h |    1 
 2 files changed, 55 insertions(+), 8 deletions(-)

diff -r 9d2a45d4b6c6 -r fb58da516749 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Wed May 07 09:17:52 2008 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Wed May 07 09:19:40 2008 +0100
@@ -678,17 +678,63 @@ void dma_pte_free_pagetable(struct domai
     }
 }
 
- /* free all VT-d page tables when shut down or destroy domain. */
+static void iommu_free_next_pagetable(u64 pt_maddr, unsigned long index,
+                                      int level)
+{
+    struct acpi_drhd_unit *drhd;
+    unsigned long next_index;
+    struct dma_pte *pt_vaddr, *pde;
+    int next_level;
+
+    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 )
+    {
+        next_level = level - 1;
+        if ( next_level > 1 )
+        {
+            next_index = 0;
+            do
+            {
+                iommu_free_next_pagetable(pde->val,
+                                          next_index, next_level);
+                next_index++;
+            } while ( next_index < PTE_NUM );
+        }
+
+        dma_clear_pte(*pde);
+        drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
+        iommu_flush_cache_entry(drhd->iommu, pde);
+        free_pgtable_maddr(pde->val);
+        unmap_vtd_domain_page(pt_vaddr);
+    }
+    else
+        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)
 {
+    unsigned long index;
     struct hvm_iommu *hd = domain_hvm_iommu(domain);
-    int addr_width = agaw_to_width(hd->agaw);
-    u64 start, end;
-
-    start = 0;
-    end = (((u64)1) << addr_width) - 1;
-
-    dma_pte_free_pagetable(domain, start, end);
+    int total_level = agaw_to_level(hd->agaw);
+
+    if ( hd->pgd_maddr != 0 )
+    {
+        index = 0;
+        do
+        {
+            iommu_free_next_pagetable(hd->pgd_maddr,
+                                      index, total_level + 1);
+            index++;
+        } while ( index < PTE_NUM );
+
+        free_pgtable_maddr(hd->pgd_maddr);
+        hd->pgd_maddr = 0;
+    }
 }
 
 static int iommu_set_root_entry(struct iommu *iommu)
diff -r 9d2a45d4b6c6 -r fb58da516749 xen/drivers/passthrough/vtd/iommu.h
--- a/xen/drivers/passthrough/vtd/iommu.h       Wed May 07 09:17:52 2008 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.h       Wed May 07 09:19:40 2008 +0100
@@ -235,6 +235,7 @@ struct context_entry {
 /* page table handling */
 #define LEVEL_STRIDE       (9)
 #define LEVEL_MASK         ((1 << LEVEL_STRIDE) - 1)
+#define PTE_NUM            (1 << LEVEL_STRIDE)
 #define agaw_to_level(val) ((val) + 2)
 #define agaw_to_width(val) (30 + val * LEVEL_STRIDE)
 #define width_to_agaw(w)   ((w - 30)/LEVEL_STRIDE)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] VT-d: Fix free VT-d page table issue, Xen patchbot-unstable <=