diff options
author | Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> | 2013-07-16 11:56:13 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-07-16 11:56:13 +0200 |
commit | 5d0ca62156d734a757656b9bcb6bf17ee76d37b4 (patch) | |
tree | 48233d3326c5d286f0d94bbe025559d6e852b004 /xen/drivers/passthrough | |
parent | c610867bf4b3a1e92a7f2a1a95e4e625160be956 (diff) | |
download | xen-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.c | 61 |
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); +} |