VT-d: Improve page table debug output
authorKeir Fraser <keir.fraser@citrix.com>
Sat, 24 May 2008 08:35:05 +0000 (09:35 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Sat, 24 May 2008 08:35:05 +0000 (09:35 +0100)
Ignore 'current' domain when dumping VT-d page tables.  Also add page
type summary for domain pages output.

Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com>
xen/drivers/passthrough/vtd/extern.h
xen/drivers/passthrough/vtd/iommu.c
xen/drivers/passthrough/vtd/utils.c

index 7d449ab2e996f5c51c3f6c1998fae6aa6284a171..300cf646bc246363a52935624bf632f852aabb8a 100644 (file)
@@ -27,8 +27,7 @@ extern struct qi_ctrl *qi_ctrl;
 extern struct ir_ctrl *ir_ctrl;
 
 void print_iommu_regs(struct acpi_drhd_unit *drhd);
-void print_vtd_entries(struct domain *d, struct iommu *iommu,
-                       int bus, int devfn, unsigned long gmfn);
+void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn);
 void pdev_flr(u8 bus, u8 devfn);
 
 int qinval_setup(struct iommu *iommu);
index e7a482465587177c0d7097bf872923b1b995c024..e967188084a88b8f48fbb5f06c1d68e72ba9fee1 100644 (file)
@@ -777,16 +777,17 @@ int iommu_disable_translation(struct iommu *iommu)
 
 static struct iommu *vector_to_iommu[NR_VECTORS];
 static int iommu_page_fault_do_one(struct iommu *iommu, int type,
-                                   u8 fault_reason, u16 source_id, u32 addr)
+                                   u8 fault_reason, u16 source_id, u64 addr)
 {
     dprintk(XENLOG_WARNING VTDPREFIX,
-            "iommu_fault:%s: %x:%x.%x addr %x REASON %x iommu->reg = %p\n",
+            "iommu_fault:%s: %x:%x.%x addr %"PRIx64" REASON %x "
+            "iommu->reg = %p\n",
             (type ? "DMA Read" : "DMA Write"), (source_id >> 8),
             PCI_SLOT(source_id & 0xFF), PCI_FUNC(source_id & 0xFF), addr,
             fault_reason, iommu->reg);
 
     if ( fault_reason < 0x20 )
-        print_vtd_entries(current->domain, iommu, (source_id >> 8),
+        print_vtd_entries(iommu, (source_id >> 8),
                           (source_id & 0xff), (addr >> PAGE_SHIFT));
 
     return 0;
@@ -844,7 +845,8 @@ static void iommu_page_fault(int vector, void *dev_id,
     {
         u8 fault_reason;
         u16 source_id;
-        u32 guest_addr, data;
+        u32 data;
+        u64 guest_addr;
         int type;
 
         /* highest 32 bits */
index c36265e105dbedf1af966ff15c8789b953b7eec4..f8f61547e82e3f2f85bd16aac3206a3d3082ea5d 100644 (file)
@@ -213,109 +213,97 @@ u32 get_level_index(unsigned long gmfn, int level)
     return gmfn & LEVEL_MASK;
 }
 
-void print_vtd_entries(
-    struct domain *d,
-    struct iommu *iommu,
-    int bus, int devfn,
-    unsigned long gmfn)
+void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn)
 {
-    struct hvm_iommu *hd = domain_hvm_iommu(d);
-    struct acpi_drhd_unit *drhd;
     struct context_entry *ctxt_entry;
     struct root_entry *root_entry;
     struct dma_pte pte;
     u64 *l;
-    u32 l_index;
-    u32 i = 0;
-    int level = agaw_to_level(hd->agaw);
+    u32 l_index, level;
 
-    printk("print_vtd_entries: domain_id = %x bdf = %x:%x:%x gmfn = %lx\n",
-           d->domain_id, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), gmfn);
+    printk("print_vtd_entries: iommu = %p bdf = %x:%x:%x gmfn = %"PRIx64"\n",
+           iommu, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), gmfn);
 
-    if ( hd->pgd_maddr == 0 )
+    if ( iommu->root_maddr == 0 )
     {
-        printk("    hd->pgd_maddr == 0\n");
+        printk("    iommu->root_maddr = 0\n");
         return;
     }
-    printk("    hd->pgd_maddr = %"PRIx64"\n", hd->pgd_maddr);
 
-    for_each_drhd_unit ( drhd )
+    root_entry = (struct root_entry *)map_vtd_domain_page(iommu->root_maddr);
+    printk("    root_entry = %p\n", root_entry);
+    printk("    root_entry[%x] = %"PRIx64"\n", bus, root_entry[bus].val);
+    if ( !root_present(root_entry[bus]) )
     {
-        printk("---- print_vtd_entries %d ----\n", i++);
+        unmap_vtd_domain_page(root_entry);
+        printk("    root_entry[%x] not present\n", bus);
+        return;
+    }
 
-        if ( iommu->root_maddr == 0 )
-        {
-            printk("    iommu->root_maddr = 0\n");
-            continue;
-        }
+    ctxt_entry =
+        (struct context_entry *)map_vtd_domain_page(root_entry[bus].val);
+    if ( ctxt_entry == NULL )
+    {
+        unmap_vtd_domain_page(root_entry);
+        printk("    ctxt_entry == NULL\n");
+        return;
+    }
 
-        root_entry =
-            (struct root_entry *)map_vtd_domain_page(iommu->root_maddr);
-        printk("    root_entry = %p\n", root_entry);
-        printk("    root_entry[%x] = %"PRIx64"\n", bus, root_entry[bus].val);
-        if ( !root_present(root_entry[bus]) )
-        {
-            unmap_vtd_domain_page(root_entry);
-            printk("    root_entry[%x] not present\n", bus);
-            continue;
-        }
+    printk("    context = %p\n", ctxt_entry);
+    printk("    context[%x] = %"PRIx64"_%"PRIx64"\n",
+           devfn, ctxt_entry[devfn].hi, ctxt_entry[devfn].lo);
+    if ( !context_present(ctxt_entry[devfn]) )
+    {
+        unmap_vtd_domain_page(ctxt_entry);
+        unmap_vtd_domain_page(root_entry);
+        printk("    ctxt_entry[%x] not present\n", devfn);
+        return;
+    }
 
-        ctxt_entry =
-            (struct context_entry *)map_vtd_domain_page(root_entry[bus].val);
-        if ( ctxt_entry == NULL )
-        {
-            unmap_vtd_domain_page(root_entry);
-            printk("    ctxt_entry == NULL\n");
-            continue;
-        }
+    level = agaw_to_level(context_address_width(ctxt_entry[devfn]));
+    if ( level != VTD_PAGE_TABLE_LEVEL_3 &&
+         level != VTD_PAGE_TABLE_LEVEL_4)
+    {
+        unmap_vtd_domain_page(ctxt_entry);
+        unmap_vtd_domain_page(root_entry);
+        printk("Unsupported VTD page table level (%d)!\n", level);
+    }
 
-        printk("    context = %p\n", ctxt_entry);
-        printk("    context[%x] = %"PRIx64" %"PRIx64"\n",
-               devfn, ctxt_entry[devfn].hi, ctxt_entry[devfn].lo);
-        if ( !context_present(ctxt_entry[devfn]) )
+    l = maddr_to_virt(ctxt_entry[devfn].lo);
+    do
+    {
+        l = (u64*)(((unsigned long)l >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K);
+        printk("    l%d = %p\n", level, l);
+        if ( l == NULL )
         {
             unmap_vtd_domain_page(ctxt_entry);
             unmap_vtd_domain_page(root_entry);
-            printk("    ctxt_entry[%x] not present\n", devfn);
-            continue;
+            printk("    l%d == NULL\n", level);
+            break;
         }
+        l_index = get_level_index(gmfn, level);
+        printk("    l%d_index = %x\n", level, l_index);
+        printk("    l%d[%x] = %"PRIx64"\n", level, l_index, l[l_index]);
 
-        if ( level != VTD_PAGE_TABLE_LEVEL_3 &&
-             level != VTD_PAGE_TABLE_LEVEL_4)
+        pte.val = l[l_index];
+        if ( !dma_pte_present(pte) )
         {
             unmap_vtd_domain_page(ctxt_entry);
             unmap_vtd_domain_page(root_entry);
-            printk("Unsupported VTD page table level (%d)!\n", level);
-            continue;
+            printk("    l%d[%x] not present\n", level, l_index);
+            break;
         }
 
-        l = maddr_to_virt(ctxt_entry[devfn].lo);
-        do
-        {
-            l = (u64*)(((unsigned long)l >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K);
-            printk("    l%d = %p\n", level, l);
-            if ( l == NULL )
-            {
-                unmap_vtd_domain_page(ctxt_entry);
-                unmap_vtd_domain_page(root_entry);
-                printk("    l%d == NULL\n", level);
-                break;
-            }
-            l_index = get_level_index(gmfn, level);
-            printk("    l%d_index = %x\n", level, l_index);
-            printk("    l%d[%x] = %"PRIx64"\n", level, l_index, l[l_index]);
-
-            pte.val = l[l_index];
-            if ( !dma_pte_present(pte) )
-            {
-                unmap_vtd_domain_page(ctxt_entry);
-                unmap_vtd_domain_page(root_entry);
-                printk("    l%d[%x] not present\n", level, l_index);
-                break;
-            }
-
-            l = maddr_to_virt(l[l_index]);
-        } while ( --level );
-    }
+        l = maddr_to_virt(l[l_index]);
+    } while ( --level );
 }
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */