Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * arch/xtensa/kernel/traps.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Exception handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Derived from code with the following copyrights:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 1994 - 1999 by Ralf Baechle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Modified for R3000 by Paul M. Antoine, 1995, 1996
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Complete output from die() by Ulf Carlsson, 1998
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Copyright (C) 1999 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Essentially rewritten for the Xtensa architecture port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * Copyright (C) 2001 - 2013 Tensilica Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * Joe Taylor	<joe@tensilica.com, joetylr@yahoo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * Chris Zankel	<chris@zankel.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * Marc Gauthier<marc@tensilica.com, marc@alumni.uwaterloo.ca>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * Kevin Chea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/sched/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/stringify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <linux/kallsyms.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/hardirq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <asm/stacktrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include <asm/timex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <asm/traps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <asm/hw_breakpoint.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * Machine specific interrupt handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) extern void kernel_exception(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) extern void user_exception(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) extern void fast_illegal_instruction_user(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) extern void fast_syscall_user(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) extern void fast_alloca(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) extern void fast_unaligned(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) extern void fast_second_level_miss(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) extern void fast_store_prohibited(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) extern void fast_coprocessor(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) extern void do_illegal_instruction (struct pt_regs*);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) extern void do_interrupt (struct pt_regs*);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) extern void do_nmi(struct pt_regs *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) extern void do_unaligned_user (struct pt_regs*);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) extern void do_multihit (struct pt_regs*, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) extern void do_page_fault (struct pt_regs*, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) extern void do_debug (struct pt_regs*);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) extern void system_call (struct pt_regs*);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * The vector table must be preceded by a save area (which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * implies it must be in RAM, unless one places RAM immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * before a ROM and puts the vector at the start of the ROM (!))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define KRNL		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define USER		0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define COPROCESSOR(x)							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) { EXCCAUSE_COPROCESSOR ## x ## _DISABLED, USER, fast_coprocessor }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	int cause;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	int fast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	void* handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) } dispatch_init_table_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static dispatch_init_table_t __initdata dispatch_init_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #ifdef CONFIG_USER_ABI_CALL0_PROBE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) { EXCCAUSE_ILLEGAL_INSTRUCTION,	USER,	   fast_illegal_instruction_user },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) { EXCCAUSE_ILLEGAL_INSTRUCTION,	0,	   do_illegal_instruction},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) { EXCCAUSE_SYSTEM_CALL,		USER,	   fast_syscall_user },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) { EXCCAUSE_SYSTEM_CALL,		0,	   system_call },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) /* EXCCAUSE_INSTRUCTION_FETCH unhandled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) /* EXCCAUSE_LOAD_STORE_ERROR unhandled*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) { EXCCAUSE_LEVEL1_INTERRUPT,	0,	   do_interrupt },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) { EXCCAUSE_ALLOCA,		USER|KRNL, fast_alloca },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* EXCCAUSE_PRIVILEGED unhandled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #ifdef CONFIG_XTENSA_UNALIGNED_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) { EXCCAUSE_UNALIGNED,		USER,	   fast_unaligned },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) { EXCCAUSE_UNALIGNED,		0,	   do_unaligned_user },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) { EXCCAUSE_UNALIGNED,		KRNL,	   fast_unaligned },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) { EXCCAUSE_ITLB_MISS,		0,	   do_page_fault },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) { EXCCAUSE_ITLB_MISS,		USER|KRNL, fast_second_level_miss},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) { EXCCAUSE_ITLB_MULTIHIT,		0,	   do_multihit },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) { EXCCAUSE_ITLB_PRIVILEGE,	0,	   do_page_fault },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* EXCCAUSE_SIZE_RESTRICTION unhandled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) { EXCCAUSE_FETCH_CACHE_ATTRIBUTE,	0,	   do_page_fault },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) { EXCCAUSE_DTLB_MISS,		USER|KRNL, fast_second_level_miss},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) { EXCCAUSE_DTLB_MISS,		0,	   do_page_fault },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) { EXCCAUSE_DTLB_MULTIHIT,		0,	   do_multihit },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) { EXCCAUSE_DTLB_PRIVILEGE,	0,	   do_page_fault },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* EXCCAUSE_DTLB_SIZE_RESTRICTION unhandled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) { EXCCAUSE_STORE_CACHE_ATTRIBUTE,	USER|KRNL, fast_store_prohibited },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) { EXCCAUSE_STORE_CACHE_ATTRIBUTE,	0,	   do_page_fault },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) { EXCCAUSE_LOAD_CACHE_ATTRIBUTE,	0,	   do_page_fault },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #endif /* CONFIG_MMU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #if XTENSA_HAVE_COPROCESSOR(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) COPROCESSOR(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #if XTENSA_HAVE_COPROCESSOR(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) COPROCESSOR(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #if XTENSA_HAVE_COPROCESSOR(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) COPROCESSOR(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #if XTENSA_HAVE_COPROCESSOR(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) COPROCESSOR(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #if XTENSA_HAVE_COPROCESSOR(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) COPROCESSOR(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #if XTENSA_HAVE_COPROCESSOR(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) COPROCESSOR(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #if XTENSA_HAVE_COPROCESSOR(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) COPROCESSOR(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #if XTENSA_HAVE_COPROCESSOR(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) COPROCESSOR(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #if XTENSA_FAKE_NMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { EXCCAUSE_MAPPED_NMI,			0,		do_nmi },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) { EXCCAUSE_MAPPED_DEBUG,		0,		do_debug },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) { -1, -1, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* The exception table <exc_table> serves two functions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * 1. it contains three dispatch tables (fast_user, fast_kernel, default-c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  * 2. it is a temporary memory buffer for the exception handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) DEFINE_PER_CPU(struct exc_table, exc_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) DEFINE_PER_CPU(struct debug_table, debug_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) void die(const char*, struct pt_regs*, long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) __die_if_kernel(const char *str, struct pt_regs *regs, long err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (!user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		die(str, regs, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * Unhandled Exceptions. Kill user task or panic if in kernel space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) void do_unhandled(struct pt_regs *regs, unsigned long exccause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	__die_if_kernel("Caught unhandled exception - should not happen",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			regs, SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	/* If in user mode, send SIGILL signal to current process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	pr_info_ratelimited("Caught unhandled exception in '%s' "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			    "(pid = %d, pc = %#010lx) - should not happen\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			    "\tEXCCAUSE is %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			    current->comm, task_pid_nr(current), regs->pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			    exccause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * Multi-hit exception. This if fatal!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) void do_multihit(struct pt_regs *regs, unsigned long exccause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	die("Caught multihit exception", regs, SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  * IRQ handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) extern void do_IRQ(int, struct pt_regs *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #if XTENSA_FAKE_NMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define IS_POW2(v) (((v) & ((v) - 1)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #if !(PROFILING_INTLEVEL == XCHAL_EXCM_LEVEL && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)       IS_POW2(XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #warning "Fake NMI is requested for PMM, but there are other IRQs at or above its level."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #warning "Fake NMI will be used, but there will be a bugcheck if one of those IRQs fire."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static inline void check_valid_nmi(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	unsigned intread = xtensa_get_sr(interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	unsigned intenable = xtensa_get_sr(intenable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	BUG_ON(intread & intenable &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	       ~(XTENSA_INTLEVEL_ANDBELOW_MASK(PROFILING_INTLEVEL) ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		 XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL) ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		 BIT(XCHAL_PROFILING_INTERRUPT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static inline void check_valid_nmi(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) irqreturn_t xtensa_pmu_irq_handler(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) DEFINE_PER_CPU(unsigned long, nmi_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) void do_nmi(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	struct pt_regs *old_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	if ((regs->ps & PS_INTLEVEL_MASK) < LOCKLEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		trace_hardirqs_off();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	old_regs = set_irq_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	nmi_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	++*this_cpu_ptr(&nmi_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	check_valid_nmi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	xtensa_pmu_irq_handler(0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	nmi_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	set_irq_regs(old_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) void do_interrupt(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	static const unsigned int_level_mask[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		XCHAL_INTLEVEL1_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		XCHAL_INTLEVEL2_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		XCHAL_INTLEVEL3_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		XCHAL_INTLEVEL4_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		XCHAL_INTLEVEL5_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		XCHAL_INTLEVEL6_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		XCHAL_INTLEVEL7_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	struct pt_regs *old_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	trace_hardirqs_off();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	old_regs = set_irq_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	irq_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		unsigned intread = xtensa_get_sr(interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		unsigned intenable = xtensa_get_sr(intenable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		unsigned int_at_level = intread & intenable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		unsigned level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		for (level = LOCKLEVEL; level > 0; --level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			if (int_at_level & int_level_mask[level]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 				int_at_level &= int_level_mask[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		if (level == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		do_IRQ(__ffs(int_at_level), regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	irq_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	set_irq_regs(old_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  * Illegal instruction. Fatal if in kernel space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) do_illegal_instruction(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	__die_if_kernel("Illegal instruction in kernel", regs, SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	/* If in user mode, send SIGILL signal to current process. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	pr_info_ratelimited("Illegal Instruction in '%s' (pid = %d, pc = %#010lx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			    current->comm, task_pid_nr(current), regs->pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)  * Handle unaligned memory accesses from user space. Kill task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)  * If CONFIG_UNALIGNED_USER is not set, we don't allow unaligned memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)  * accesses causes from user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) do_unaligned_user (struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	__die_if_kernel("Unhandled unaligned exception in kernel",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			regs, SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	current->thread.bad_vaddr = regs->excvaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	current->thread.error_code = -3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	pr_info_ratelimited("Unaligned memory access to %08lx in '%s' "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			    "(pid = %d, pc = %#010lx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			    regs->excvaddr, current->comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			    task_pid_nr(current), regs->pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	force_sig_fault(SIGBUS, BUS_ADRALN, (void *) regs->excvaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* Handle debug events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  * When CONFIG_HAVE_HW_BREAKPOINT is on this handler is called with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)  * preemption disabled to avoid rescheduling and keep mapping of hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)  * breakpoint structures to debug registers intact, so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)  * DEBUGCAUSE.DBNUM could be used in case of data breakpoint hit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) do_debug(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #ifdef CONFIG_HAVE_HW_BREAKPOINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	int ret = check_hw_breakpoint(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	__die_if_kernel("Breakpoint in kernel", regs, SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	/* If in user mode, send SIGTRAP signal to current process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	force_sig(SIGTRAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #define set_handler(type, cause, handler)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	do {								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		unsigned int cpu;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		for_each_possible_cpu(cpu)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 			per_cpu(exc_table, cpu).type[cause] = (handler);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* Set exception C handler - for temporary use when probing exceptions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) void * __init trap_set_handler(int cause, void *handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	void *previous = per_cpu(exc_table, 0).default_handler[cause];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	set_handler(default_handler, cause, handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	return previous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static void trap_init_excsave(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	unsigned long excsave1 = (unsigned long)this_cpu_ptr(&exc_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	__asm__ __volatile__("wsr  %0, excsave1\n" : : "a" (excsave1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static void trap_init_debug(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	unsigned long debugsave = (unsigned long)this_cpu_ptr(&debug_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	this_cpu_ptr(&debug_table)->debug_exception = debug_exception;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	__asm__ __volatile__("wsr %0, excsave" __stringify(XCHAL_DEBUGLEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			     :: "a"(debugsave));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)  * Initialize dispatch tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)  * The exception vectors are stored compressed the __init section in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)  * dispatch_init_table. This function initializes the following three tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)  * from that compressed table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)  * - fast user		first dispatch table for user exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)  * - fast kernel	first dispatch table for kernel exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)  * - default C-handler	C-handler called by the default fast handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)  * See vectors.S for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) void __init trap_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	/* Setup default vectors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	for (i = 0; i < EXCCAUSE_N; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		set_handler(fast_user_handler, i, user_exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		set_handler(fast_kernel_handler, i, kernel_exception);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		set_handler(default_handler, i, do_unhandled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	/* Setup specific handlers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	for(i = 0; dispatch_init_table[i].cause >= 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		int fast = dispatch_init_table[i].fast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		int cause = dispatch_init_table[i].cause;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		void *handler = dispatch_init_table[i].handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		if (fast == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			set_handler(default_handler, cause, handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		if ((fast & USER) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			set_handler(fast_user_handler, cause, handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if ((fast & KRNL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			set_handler(fast_kernel_handler, cause, handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	/* Initialize EXCSAVE_1 to hold the address of the exception table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	trap_init_excsave();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	trap_init_debug();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) void secondary_trap_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	trap_init_excsave();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	trap_init_debug();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)  * This function dumps the current valid window frame and other base registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) void show_regs(struct pt_regs * regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	int i, wmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	show_regs_print_info(KERN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	wmask = regs->wmask & ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		if ((i % 8) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 			pr_info("a%02d:", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		pr_cont(" %08lx", regs->areg[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	pr_info("pc: %08lx, ps: %08lx, depc: %08lx, excvaddr: %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		regs->pc, regs->ps, regs->depc, regs->excvaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	pr_info("lbeg: %08lx, lend: %08lx lcount: %08lx, sar: %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		regs->lbeg, regs->lend, regs->lcount, regs->sar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	if (user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		pr_cont("wb: %08lx, ws: %08lx, wmask: %08lx, syscall: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			regs->windowbase, regs->windowstart, regs->wmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 			regs->syscall);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static int show_trace_cb(struct stackframe *frame, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	const char *loglvl = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	if (kernel_text_address(frame->pc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		printk("%s [<%08lx>] %pB\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			loglvl, frame->pc, (void *)frame->pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static void show_trace(struct task_struct *task, unsigned long *sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		       const char *loglvl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		sp = stack_pointer(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	printk("%sCall Trace:\n", loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	walk_stackframe(sp, show_trace_cb, (void *)loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) #define STACK_DUMP_ENTRY_SIZE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #define STACK_DUMP_LINE_SIZE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static size_t kstack_depth_to_print = CONFIG_PRINT_STACK_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		sp = stack_pointer(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	len = min((-(size_t)sp) & (THREAD_SIZE - STACK_DUMP_ENTRY_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		  kstack_depth_to_print * STACK_DUMP_ENTRY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	printk("%sStack:\n", loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	print_hex_dump(loglvl, " ", DUMP_PREFIX_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		       STACK_DUMP_LINE_SIZE, STACK_DUMP_ENTRY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		       sp, len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	show_trace(task, sp, loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) DEFINE_SPINLOCK(die_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) void die(const char * str, struct pt_regs * regs, long err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	static int die_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	const char *pr = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	if (IS_ENABLED(CONFIG_PREEMPTION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		pr = IS_ENABLED(CONFIG_PREEMPT_RT) ? " PREEMPT_RT" : " PREEMPT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	console_verbose();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	spin_lock_irq(&die_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	pr_info("%s: sig: %ld [#%d]%s\n", str, err, ++die_counter, pr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	show_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	if (!user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		show_stack(NULL, (unsigned long *)regs->areg[1], KERN_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	spin_unlock_irq(&die_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	if (in_interrupt())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		panic("Fatal exception in interrupt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	if (panic_on_oops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		panic("Fatal exception");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	do_exit(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }