1 // SPDX-License-Identifier: GPL-2.0 !! 1 /* 2 // Copyright (C) 2018 Hangzhou C-SKY Microsyst !! 2 * This file is subject to the terms and conditions of the GNU General Public 3 !! 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> 4 #include <linux/init.h> 13 #include <linux/init.h> 5 #include <linux/interrupt.h> 14 #include <linux/interrupt.h> 6 #include <linux/irq.h> !! 15 #include <linux/kernel_stat.h> 7 #include <linux/irqchip.h> !! 16 #include <linux/proc_fs.h> 8 #include <asm/traps.h> !! 17 #include <linux/mm.h> 9 #include <asm/smp.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 void *irq_stack[NR_CPUS]; >> 29 >> 30 /* >> 31 * 'what should we do if we get a hw irq event on an illegal vector'. >> 32 * each architecture has to answer this themselves. >> 33 */ >> 34 void ack_bad_irq(unsigned int irq) >> 35 { >> 36 printk("unexpected IRQ # %d\n", irq); >> 37 } >> 38 >> 39 atomic_t irq_err_count; >> 40 >> 41 int arch_show_interrupts(struct seq_file *p, int prec) >> 42 { >> 43 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); >> 44 return 0; >> 45 } >> 46 >> 47 asmlinkage void spurious_interrupt(void) >> 48 { >> 49 atomic_inc(&irq_err_count); >> 50 } 10 51 11 void __init init_IRQ(void) 52 void __init init_IRQ(void) 12 { 53 { 13 irqchip_init(); !! 54 int i; 14 #ifdef CONFIG_SMP !! 55 unsigned int order = get_order(IRQ_STACK_SIZE); 15 setup_smp_ipi(); !! 56 >> 57 for (i = 0; i < NR_IRQS; i++) >> 58 irq_set_noprobe(i); >> 59 >> 60 arch_init_irq(); >> 61 >> 62 for_each_possible_cpu(i) { >> 63 void *s = (void *)__get_free_pages(GFP_KERNEL, order); >> 64 >> 65 irq_stack[i] = s; >> 66 pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i, >> 67 irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE); >> 68 } >> 69 } >> 70 >> 71 #ifdef CONFIG_DEBUG_STACKOVERFLOW >> 72 static inline void check_stack_overflow(void) >> 73 { >> 74 unsigned long sp; >> 75 >> 76 __asm__ __volatile__("move %0, $sp" : "=r" (sp)); >> 77 sp &= THREAD_MASK; >> 78 >> 79 /* >> 80 * Check for stack overflow: is there less than STACK_WARN free? >> 81 * STACK_WARN is defined as 1/8 of THREAD_SIZE by default. >> 82 */ >> 83 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { >> 84 printk("do_IRQ: stack overflow: %ld\n", >> 85 sp - sizeof(struct thread_info)); >> 86 dump_stack(); >> 87 } >> 88 } >> 89 #else >> 90 static inline void check_stack_overflow(void) {} 16 #endif 91 #endif >> 92 >> 93 >> 94 /* >> 95 * do_IRQ handles all normal device IRQ's (the special >> 96 * SMP cross-CPU interrupts have their own specific >> 97 * handlers). >> 98 */ >> 99 void __irq_entry do_IRQ(unsigned int irq) >> 100 { >> 101 irq_enter(); >> 102 check_stack_overflow(); >> 103 generic_handle_irq(irq); >> 104 irq_exit(); 17 } 105 } >> 106 18 107
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.