diff options
Diffstat (limited to 'arch/x86/kernel/irq_64.c')
-rw-r--r-- | arch/x86/kernel/irq_64.c | 43 |
1 files changed, 13 insertions, 30 deletions
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index 63c88e6ec025..977d8b43a0dd 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c | |||
@@ -18,6 +18,13 @@ | |||
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <asm/io_apic.h> | 19 | #include <asm/io_apic.h> |
20 | #include <asm/idle.h> | 20 | #include <asm/idle.h> |
21 | #include <asm/apic.h> | ||
22 | |||
23 | DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); | ||
24 | EXPORT_PER_CPU_SYMBOL(irq_stat); | ||
25 | |||
26 | DEFINE_PER_CPU(struct pt_regs *, irq_regs); | ||
27 | EXPORT_PER_CPU_SYMBOL(irq_regs); | ||
21 | 28 | ||
22 | /* | 29 | /* |
23 | * Probabilistic stack overflow check: | 30 | * Probabilistic stack overflow check: |
@@ -41,42 +48,18 @@ static inline void stack_overflow_check(struct pt_regs *regs) | |||
41 | #endif | 48 | #endif |
42 | } | 49 | } |
43 | 50 | ||
44 | /* | 51 | bool handle_irq(unsigned irq, struct pt_regs *regs) |
45 | * do_IRQ handles all normal device IRQ's (the special | ||
46 | * SMP cross-CPU interrupts have their own specific | ||
47 | * handlers). | ||
48 | */ | ||
49 | asmlinkage unsigned int __irq_entry do_IRQ(struct pt_regs *regs) | ||
50 | { | 52 | { |
51 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
52 | struct irq_desc *desc; | 53 | struct irq_desc *desc; |
53 | 54 | ||
54 | /* high bit used in ret_from_ code */ | ||
55 | unsigned vector = ~regs->orig_ax; | ||
56 | unsigned irq; | ||
57 | |||
58 | exit_idle(); | ||
59 | irq_enter(); | ||
60 | irq = __get_cpu_var(vector_irq)[vector]; | ||
61 | |||
62 | stack_overflow_check(regs); | 55 | stack_overflow_check(regs); |
63 | 56 | ||
64 | desc = irq_to_desc(irq); | 57 | desc = irq_to_desc(irq); |
65 | if (likely(desc)) | 58 | if (unlikely(!desc)) |
66 | generic_handle_irq_desc(irq, desc); | 59 | return false; |
67 | else { | ||
68 | if (!disable_apic) | ||
69 | ack_APIC_irq(); | ||
70 | |||
71 | if (printk_ratelimit()) | ||
72 | printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n", | ||
73 | __func__, smp_processor_id(), vector); | ||
74 | } | ||
75 | |||
76 | irq_exit(); | ||
77 | 60 | ||
78 | set_irq_regs(old_regs); | 61 | generic_handle_irq_desc(irq, desc); |
79 | return 1; | 62 | return true; |
80 | } | 63 | } |
81 | 64 | ||
82 | #ifdef CONFIG_HOTPLUG_CPU | 65 | #ifdef CONFIG_HOTPLUG_CPU |
@@ -100,7 +83,7 @@ void fixup_irqs(void) | |||
100 | /* interrupt's are disabled at this point */ | 83 | /* interrupt's are disabled at this point */ |
101 | spin_lock(&desc->lock); | 84 | spin_lock(&desc->lock); |
102 | 85 | ||
103 | affinity = &desc->affinity; | 86 | affinity = desc->affinity; |
104 | if (!irq_has_action(irq) || | 87 | if (!irq_has_action(irq) || |
105 | cpumask_equal(affinity, cpu_online_mask)) { | 88 | cpumask_equal(affinity, cpu_online_mask)) { |
106 | spin_unlock(&desc->lock); | 89 | spin_unlock(&desc->lock); |