1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Code to handle x86 style IRQs plus some generic interrupt stuff. 7 * 8 * Copyright (C) 1992 Linus Torvalds 9 * Copyright (C) 1994 - 2000 Ralf Baechle 10 */ 11 #include <linux/kernel.h> 12 #include <linux/delay.h> 13 #include <linux/init.h> 14 #include <linux/interrupt.h> 15 #include <linux/kernel_stat.h> 16 #include <linux/proc_fs.h> 17 #include <linux/mm.h> 18 #include <linux/random.h> 19 #include <linux/sched.h> 20 #include <linux/seq_file.h> 21 #include <linux/kallsyms.h> 22 #include <linux/kgdb.h> 23 #include <linux/ftrace.h> 24 25 #include <linux/atomic.h> 26 #include <asm/uaccess.h> 27 28 /* 29 * 'what should we do if we get a hw irq event on an illegal vector'. 30 * each architecture has to answer this themselves. 31 */ 32 void ack_bad_irq(unsigned int irq) 33 { 34 printk("unexpected IRQ # %d\n", irq); 35 } 36 37 atomic_t irq_err_count; 38 39 int arch_show_interrupts(struct seq_file *p, int prec) 40 { 41 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); 42 return 0; 43 } 44 45 asmlinkage void spurious_interrupt(void) 46 { 47 atomic_inc(&irq_err_count); 48 } 49 50 void __init init_IRQ(void) 51 { 52 int i; 53 54 for (i = 0; i < NR_IRQS; i++) 55 irq_set_noprobe(i); 56 57 arch_init_irq(); 58 } 59 60 #ifdef CONFIG_DEBUG_STACKOVERFLOW 61 static inline void check_stack_overflow(void) 62 { 63 unsigned long sp; 64 65 __asm__ __volatile__("move %0, $sp" : "=r" (sp)); 66 sp &= THREAD_MASK; 67 68 /* 69 * Check for stack overflow: is there less than STACK_WARN free? 70 * STACK_WARN is defined as 1/8 of THREAD_SIZE by default. 71 */ 72 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { 73 printk("do_IRQ: stack overflow: %ld\n", 74 sp - sizeof(struct thread_info)); 75 dump_stack(); 76 } 77 } 78 #else 79 static inline void check_stack_overflow(void) {} 80 #endif 81 82 83 /* 84 * do_IRQ handles all normal device IRQ's (the special 85 * SMP cross-CPU interrupts have their own specific 86 * handlers). 87 */ 88 void __irq_entry do_IRQ(unsigned int irq) 89 { 90 irq_enter(); 91 check_stack_overflow(); 92 generic_handle_irq(irq); 93 irq_exit(); 94 } 95 96