aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/passthrough
diff options
context:
space:
mode:
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>2013-07-16 11:56:13 +0200
committerJan Beulich <jbeulich@suse.com>2013-07-16 11:56:13 +0200
commit5d0ca62156d734a757656b9bcb6bf17ee76d37b4 (patch)
tree48233d3326c5d286f0d94bbe025559d6e852b004 /xen/drivers/passthrough
parentc610867bf4b3a1e92a7f2a1a95e4e625160be956 (diff)
downloadxen-5d0ca62156d734a757656b9bcb6bf17ee76d37b4.tar.gz
xen-5d0ca62156d734a757656b9bcb6bf17ee76d37b4.tar.bz2
xen-5d0ca62156d734a757656b9bcb6bf17ee76d37b4.zip
AMD IOMMU: Add debug-key for dumping IRTEs
Support debug-key "V" to allow IOMMU IRTE dumping. Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Diffstat (limited to 'xen/drivers/passthrough')
-rw-r--r--xen/drivers/passthrough/amd/iommu_intr.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c
index 62bdc7b6fd..bae0be76bd 100644
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -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);
+}