AMD IOMMU: Add debug-key for dumping IRTEs
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Tue, 16 Jul 2013 09:56:13 +0000 (11:56 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 16 Jul 2013 09:56:13 +0000 (11:56 +0200)
Support debug-key "V" to allow IOMMU IRTE dumping.

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
xen/drivers/passthrough/amd/iommu_intr.c

index 62bdc7b6fdce8589f9c37d3485975da9b87408c1..bae0be76bd6286a0f0c7fff84085c82a7af8f172 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/amd-iommu.h>
 #include <asm/hvm/svm/amd-iommu-proto.h>
 #include <asm/io_apic.h>
+#include <xen/keyhandler.h>
 
 #define INTREMAP_TABLE_ORDER    1
 #define INTREMAP_LENGTH 0xB
@@ -34,6 +35,14 @@ void *shared_intremap_table;
 unsigned long *shared_intremap_inuse;
 static DEFINE_SPINLOCK(shared_intremap_lock);
 
+static void dump_intremap_tables(unsigned char key);
+
+static struct keyhandler dump_intremap = {
+    .diagnostic = 0,
+    .u.fn = dump_intremap_tables,
+    .desc = "dump IOMMU intremap tables"
+};
+
 static spinlock_t* get_intremap_lock(int seg, int req_id)
 {
     return (amd_iommu_perdev_intremap ?
@@ -260,6 +269,9 @@ int __init amd_iommu_setup_ioapic_remapping(void)
             }
         }
     }
+
+    register_keyhandler('V', &dump_intremap);
+
     return 0;
 }
 
@@ -592,3 +604,52 @@ int __init amd_setup_hpet_msi(struct msi_desc *msi_desc)
 
     return 0;
 }
+
+static void dump_intremap_table(const u32 *table)
+{
+    u32 count;
+
+    if ( !table )
+        return;
+
+    for ( count = 0; count < INTREMAP_ENTRIES; count++ )
+    {
+        if ( !table[count] )
+            continue;
+        printk("    IRTE[%03x] %08x\n", count, table[count]);
+    }
+}
+
+static int dump_intremap_mapping(u16 seg, struct ivrs_mappings *ivrs_mapping)
+{
+    unsigned long flags;
+
+    if ( !ivrs_mapping )
+        return 0;
+
+    printk("  %04x:%02x:%02x:%u:\n", seg,
+           PCI_BUS(ivrs_mapping->dte_requestor_id),
+           PCI_SLOT(ivrs_mapping->dte_requestor_id),
+           PCI_FUNC(ivrs_mapping->dte_requestor_id));
+
+    spin_lock_irqsave(&(ivrs_mapping->intremap_lock), flags);
+    dump_intremap_table(ivrs_mapping->intremap_table);
+    spin_unlock_irqrestore(&(ivrs_mapping->intremap_lock), flags);
+
+    return 0;
+}
+
+static void dump_intremap_tables(unsigned char key)
+{
+    unsigned long flags;
+
+    printk("--- Dumping Per-dev IOMMU Interrupt Remapping Table ---\n");
+
+    iterate_ivrs_entries(dump_intremap_mapping);
+
+    printk("--- Dumping Shared IOMMU Interrupt Remapping Table ---\n");
+
+    spin_lock_irqsave(&shared_intremap_lock, flags);
+    dump_intremap_table(shared_intremap_table);
+    spin_unlock_irqrestore(&shared_intremap_lock, flags);
+}