aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/irq.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2012-03-30 08:50:33 +0100
committerKeir Fraser <keir@xen.org>2012-03-30 08:50:33 +0100
commitb57458c1d02b3ec8d8752e9cfdb17d1a89157f03 (patch)
tree002213ad5985f962d2cd37f073dee341582682c1 /xen/arch/x86/irq.c
parentd928515d763dbcb90b017460c22c990e02a2b9d8 (diff)
downloadxen-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.c36
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);
}