diff options
author | Keir Fraser <keir@xen.org> | 2012-03-30 08:50:33 +0100 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2012-03-30 08:50:33 +0100 |
commit | b57458c1d02b3ec8d8752e9cfdb17d1a89157f03 (patch) | |
tree | 002213ad5985f962d2cd37f073dee341582682c1 /xen/arch/x86/irq.c | |
parent | d928515d763dbcb90b017460c22c990e02a2b9d8 (diff) | |
download | xen-b57458c1d02b3ec8d8752e9cfdb17d1a89157f03.tar.gz xen-b57458c1d02b3ec8d8752e9cfdb17d1a89157f03.tar.bz2 xen-b57458c1d02b3ec8d8752e9cfdb17d1a89157f03.zip |
x86: All vectored interrupts go through do_IRQ().
Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/irq.c')
-rw-r--r-- | xen/arch/x86/irq.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 0e5b9c0de0..ab5fd15556 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -610,14 +610,11 @@ void move_native_irq(struct irq_desc *desc) static void dump_irqs(unsigned char key); -fastcall void smp_irq_move_cleanup_interrupt(struct cpu_user_regs *regs) +void irq_move_cleanup_interrupt(struct cpu_user_regs *regs) { unsigned vector, me; - struct cpu_user_regs *old_regs = set_irq_regs(regs); ack_APIC_irq(); - this_cpu(irq_count)++; - irq_enter(); me = smp_processor_id(); for (vector = FIRST_DYNAMIC_VECTOR; vector < NR_VECTORS; vector++) { @@ -687,9 +684,6 @@ fastcall void smp_irq_move_cleanup_interrupt(struct cpu_user_regs *regs) unlock: spin_unlock(&desc->lock); } - - irq_exit(); - set_irq_regs(old_regs); } static void send_cleanup_vector(struct irq_desc *desc) @@ -770,6 +764,14 @@ void pirq_set_affinity(struct domain *d, int pirq, const cpumask_t *mask) DEFINE_PER_CPU(unsigned int, irq_count); +static void (*direct_apic_vector[NR_VECTORS])(struct cpu_user_regs *); +void set_direct_apic_vector( + uint8_t vector, void (*handler)(struct cpu_user_regs *)) +{ + BUG_ON(direct_apic_vector[vector] != NULL); + direct_apic_vector[vector] = handler; +} + void do_IRQ(struct cpu_user_regs *regs) { struct irqaction *action; @@ -780,20 +782,21 @@ void do_IRQ(struct cpu_user_regs *regs) struct cpu_user_regs *old_regs = set_irq_regs(regs); perfc_incr(irqs); - this_cpu(irq_count)++; + irq_enter(); if (irq < 0) { - ack_APIC_irq(); - printk("%s: %d.%d No irq handler for vector (irq %d)\n", - __func__, smp_processor_id(), vector, irq); - set_irq_regs(old_regs); - TRACE_1D(TRC_HW_IRQ_UNMAPPED_VECTOR, vector); - return; + if (direct_apic_vector[vector] != NULL) { + (*direct_apic_vector[vector])(regs); + } else { + ack_APIC_irq(); + printk("%s: %d.%d No irq handler for vector (irq %d)\n", + __func__, smp_processor_id(), vector, irq); + TRACE_1D(TRC_HW_IRQ_UNMAPPED_VECTOR, vector); + } + goto out_no_unlock; } - irq_enter(); - desc = irq_to_desc(irq); spin_lock(&desc->lock); @@ -863,6 +866,7 @@ void do_IRQ(struct cpu_user_regs *regs) desc->handler->end(desc, regs->entry_vector); out_no_end: spin_unlock(&desc->lock); + out_no_unlock: irq_exit(); set_irq_regs(old_regs); } |