diff options
Diffstat (limited to 'arch/x86/kernel/irq_64.c')
-rw-r--r-- | arch/x86/kernel/irq_64.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index 6b5c730d67b9..3aac15466a91 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c | |||
@@ -20,6 +20,26 @@ | |||
20 | 20 | ||
21 | atomic_t irq_err_count; | 21 | atomic_t irq_err_count; |
22 | 22 | ||
23 | /* | ||
24 | * 'what should we do if we get a hw irq event on an illegal vector'. | ||
25 | * each architecture has to answer this themselves. | ||
26 | */ | ||
27 | void ack_bad_irq(unsigned int irq) | ||
28 | { | ||
29 | printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq); | ||
30 | /* | ||
31 | * Currently unexpected vectors happen only on SMP and APIC. | ||
32 | * We _must_ ack these because every local APIC has only N | ||
33 | * irq slots per priority level, and a 'hanging, unacked' IRQ | ||
34 | * holds up an irq slot - in excessive cases (when multiple | ||
35 | * unexpected vectors occur) that might lock up the APIC | ||
36 | * completely. | ||
37 | * But don't ack when the APIC is disabled. -AK | ||
38 | */ | ||
39 | if (!disable_apic) | ||
40 | ack_APIC_irq(); | ||
41 | } | ||
42 | |||
23 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | 43 | #ifdef CONFIG_DEBUG_STACKOVERFLOW |
24 | /* | 44 | /* |
25 | * Probabilistic stack overflow check: | 45 | * Probabilistic stack overflow check: |
@@ -33,11 +53,11 @@ static inline void stack_overflow_check(struct pt_regs *regs) | |||
33 | u64 curbase = (u64)task_stack_page(current); | 53 | u64 curbase = (u64)task_stack_page(current); |
34 | static unsigned long warned = -60*HZ; | 54 | static unsigned long warned = -60*HZ; |
35 | 55 | ||
36 | if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE && | 56 | if (regs->sp >= curbase && regs->sp <= curbase + THREAD_SIZE && |
37 | regs->rsp < curbase + sizeof(struct thread_info) + 128 && | 57 | regs->sp < curbase + sizeof(struct thread_info) + 128 && |
38 | time_after(jiffies, warned + 60*HZ)) { | 58 | time_after(jiffies, warned + 60*HZ)) { |
39 | printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n", | 59 | printk("do_IRQ: %s near stack overflow (cur:%Lx,sp:%lx)\n", |
40 | current->comm, curbase, regs->rsp); | 60 | current->comm, curbase, regs->sp); |
41 | show_stack(NULL,NULL); | 61 | show_stack(NULL,NULL); |
42 | warned = jiffies; | 62 | warned = jiffies; |
43 | } | 63 | } |
@@ -142,7 +162,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) | |||
142 | struct pt_regs *old_regs = set_irq_regs(regs); | 162 | struct pt_regs *old_regs = set_irq_regs(regs); |
143 | 163 | ||
144 | /* high bit used in ret_from_ code */ | 164 | /* high bit used in ret_from_ code */ |
145 | unsigned vector = ~regs->orig_rax; | 165 | unsigned vector = ~regs->orig_ax; |
146 | unsigned irq; | 166 | unsigned irq; |
147 | 167 | ||
148 | exit_idle(); | 168 | exit_idle(); |