diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-03-17 16:37:18 -0700 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-24 23:57:32 +0200 |
commit | ee523ca1e456d754d66be6deab910131e4e1dbf8 (patch) | |
tree | 346c3bf4f701a07b124af72a3da4577b2e5dcb3b /arch/x86/xen/events.c | |
parent | e2a81baf6604a2e08e10c7405b0349106f77c8af (diff) | |
download | lwn-ee523ca1e456d754d66be6deab910131e4e1dbf8.tar.gz lwn-ee523ca1e456d754d66be6deab910131e4e1dbf8.zip |
xen: implement a debug-interrupt handler
Xen supports the notion of a debug interrupt which can be triggered
from the console. For now this is implemented to show pending events,
masks and each CPU's pending event set.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/xen/events.c')
-rw-r--r-- | arch/x86/xen/events.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/arch/x86/xen/events.c b/arch/x86/xen/events.c index dcf613e17581..0140981e93c4 100644 --- a/arch/x86/xen/events.c +++ b/arch/x86/xen/events.c @@ -455,6 +455,53 @@ void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector) notify_remote_via_irq(irq); } +irqreturn_t xen_debug_interrupt(int irq, void *dev_id) +{ + struct shared_info *sh = HYPERVISOR_shared_info; + int cpu = smp_processor_id(); + int i; + unsigned long flags; + static DEFINE_SPINLOCK(debug_lock); + + spin_lock_irqsave(&debug_lock, flags); + + printk("vcpu %d\n ", cpu); + + for_each_online_cpu(i) { + struct vcpu_info *v = per_cpu(xen_vcpu, i); + printk("%d: masked=%d pending=%d event_sel %08lx\n ", i, + (get_irq_regs() && i == cpu) ? !(get_irq_regs()->flags & X86_EFLAGS_IF) : v->evtchn_upcall_mask, + v->evtchn_upcall_pending, + v->evtchn_pending_sel); + } + printk("pending:\n "); + for(i = ARRAY_SIZE(sh->evtchn_pending)-1; i >= 0; i--) + printk("%08lx%s", sh->evtchn_pending[i], + i % 8 == 0 ? "\n " : " "); + printk("\nmasks:\n "); + for(i = ARRAY_SIZE(sh->evtchn_mask)-1; i >= 0; i--) + printk("%08lx%s", sh->evtchn_mask[i], + i % 8 == 0 ? "\n " : " "); + + printk("\nunmasked:\n "); + for(i = ARRAY_SIZE(sh->evtchn_mask)-1; i >= 0; i--) + printk("%08lx%s", sh->evtchn_pending[i] & ~sh->evtchn_mask[i], + i % 8 == 0 ? "\n " : " "); + + printk("\npending list:\n"); + for(i = 0; i < NR_EVENT_CHANNELS; i++) { + if (sync_test_bit(i, sh->evtchn_pending)) { + printk(" %d: event %d -> irq %d\n", + cpu_evtchn[i], i, + evtchn_to_irq[i]); + } + } + + spin_unlock_irqrestore(&debug_lock, flags); + + return IRQ_HANDLED; +} + /* * Search the CPUs pending events bitmasks. For each one found, map |