15 #include <linux/sched.h>
16 #include <linux/kernel.h>
17 #include <linux/string.h>
18 #include <linux/errno.h>
19 #include <linux/ptrace.h>
27 #include <linux/module.h>
30 #include <linux/reboot.h>
33 #include <linux/utsname.h>
34 #include <asm/uaccess.h>
40 #include <asm/debug.h>
48 #define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
52 #define FOURLONG "%08lx %08lx %08lx %08lx\n"
55 #define LONG "%016lx "
56 #define FOURLONG "%016lx %016lx %016lx %016lx\n"
66 address = *(
unsigned long *)(
current->thread.trap_tdb + 24);
68 address = regs->
psw.addr;
86 __show_trace(
unsigned long sp,
unsigned long low,
unsigned long high)
93 if (sp < low || sp > high -
sizeof(*sf))
96 printk(
"([<%016lx>] ", sf->
gprs[8] & PSW_ADDR_INSN);
97 print_symbol(
"%s)\n", sf->
gprs[8] & PSW_ADDR_INSN);
104 if (sp <= low || sp > high -
sizeof(*sf))
107 printk(
" [<%016lx>] ", sf->
gprs[8] & PSW_ADDR_INSN);
108 print_symbol(
"%s\n", sf->
gprs[8] & PSW_ADDR_INSN);
111 sp = (
unsigned long) (sf + 1);
112 if (sp <= low || sp > high -
sizeof(*regs))
115 printk(
" [<%016lx>] ", regs->
psw.addr & PSW_ADDR_INSN);
116 print_symbol(
"%s\n", regs->
psw.addr & PSW_ADDR_INSN);
124 register unsigned long __r15
asm (
"15");
127 sp = (
unsigned long) stack;
129 sp = task ? task->
thread.ksp : __r15;
131 #ifdef CONFIG_CHECK_STACK
150 register unsigned long * __r15
asm (
"15");
151 unsigned long *
stack;
155 stack = task ? (
unsigned long *) task->
thread.ksp : __r15;
162 if ((i *
sizeof(
long) % 32) == 0)
163 printk(
"%s ", i == 0 ?
"" :
"\n");
170 static void show_last_breaking_event(
struct pt_regs *regs)
173 printk(
"Last Breaking-Event-Address:\n");
174 printk(
" [<%016lx>] ", regs->
args[0] & PSW_ADDR_INSN);
175 print_symbol(
"%s\n", regs->
args[0] & PSW_ADDR_INSN);
184 printk(
"CPU: %d %s %s %.*s\n",
189 printk(
"Process %s (pid: %d, task: %p, ksp: %p)\n",
198 return (regs->
psw.mask & bits) / ((~bits + 1) & bits);
205 mode =
user_mode(regs) ?
"User" :
"Krnl";
207 mode, (
void *) regs->
psw.mask,
208 (
void *) regs->
psw.addr);
209 print_symbol(
" (%s)\n", regs->
psw.addr & PSW_ADDR_INSN);
210 printk(
" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "
234 printk(
"CPU: %d %s %s %.*s\n",
239 printk(
"Process %s (pid: %d, task: %p, ksp: %p)\n",
246 show_last_breaking_event(regs);
253 static int die_counter;
261 printk(
"%s: %04x [#%d] ", str, regs->
int_code & 0xffff, ++die_counter);
262 #ifdef CONFIG_PREEMPT
268 #ifdef CONFIG_DEBUG_PAGEALLOC
269 printk(
"DEBUG_PAGEALLOC");
279 panic(
"Fatal exception in interrupt");
281 panic(
"Fatal exception: panic_on_oops");
286 static inline void report_user_fault(
struct pt_regs *regs,
int signr)
292 if (!printk_ratelimit())
294 printk(
"User process fault: interruption code 0x%X ", regs->
int_code);
306 int si_signo,
int si_code,
char *
str)
311 regs->
int_code, si_signo) == NOTIFY_STOP)
318 info.si_addr = get_trap_ip(regs);
320 report_user_fault(regs, si_signo);
353 static void default_trap_handler(
struct pt_regs *regs)
356 report_user_fault(regs,
SIGSEGV);
359 die(regs,
"Unknown program exception");
362 #define DO_ERROR_INFO(name, signr, sicode, str) \
363 static void name(struct pt_regs *regs) \
365 do_trap(regs, signr, sicode, str); \
369 "addressing exception")
397 "transaction constraint exception")
400 static inline void do_fp_trap(
struct pt_regs *regs,
int fpc)
404 if ((fpc & 0x00000300) == 0) {
408 else if (fpc & 0x4000)
410 else if (fpc & 0x2000)
412 else if (fpc & 0x1000)
414 else if (fpc & 0x0800)
417 do_trap(regs, SIGFPE, si_code,
"floating point exception");
427 location = get_trap_ip(regs);
441 #ifdef CONFIG_MATHEMU
442 }
else if (opcode[0] == 0xb3) {
446 }
else if (opcode[0] == 0xed) {
448 (
__u32 __user *)(location+1)))
451 }
else if (*((
__u16 *) opcode) == 0xb299) {
455 }
else if (*((
__u16 *) opcode) == 0xb29c) {
459 }
else if (*((
__u16 *) opcode) == 0xb29d) {
476 #ifdef CONFIG_MATHEMU
477 if (signal == SIGFPE)
478 do_fp_trap(regs,
current->thread.fp_regs.fpc);
488 #ifdef CONFIG_MATHEMU
489 void specification_exception(
struct pt_regs *regs)
529 if (signal == SIGFPE)
530 do_fp_trap(regs,
current->thread.fp_regs.fpc);
532 do_trap(regs, signal, ILL_ILLOPN,
"specification exception");
536 "specification exception");
539 static void data_exception(
struct pt_regs *regs)
544 location = get_trap_ip(regs);
547 asm volatile(
"stfpc %0" :
"=m" (
current->thread.fp_regs.fpc));
549 #ifdef CONFIG_MATHEMU
582 (
__u32 __user *)(location+1));
586 if (opcode[1] == 0x99) {
589 }
else if (opcode[1] == 0x9c) {
592 }
else if (opcode[1] == 0x9d) {
608 if (signal == SIGFPE)
609 do_fp_trap(regs,
current->thread.fp_regs.fpc);
611 do_trap(regs, signal, ILL_ILLOPN,
"data exception");
614 static void space_switch_exception(
struct pt_regs *regs)
620 do_trap(regs, SIGILL, ILL_PRVOPC,
"space switch event");
626 printk(
"Kernel stack overflow.\n");
629 panic(
"Corrupt kernel stack, can't continue.");
638 for (i = 0; i < 128; i++)