Commit | Line | Data |
---|---|---|
5a4f7c66 PM |
1 | #include <linux/bug.h> |
2 | #include <linux/io.h> | |
3 | #include <linux/types.h> | |
4 | #include <linux/kdebug.h> | |
47a3eb95 PM |
5 | #include <linux/signal.h> |
6 | #include <linux/sched.h> | |
5a4f7c66 PM |
7 | #include <asm/system.h> |
8 | ||
9 | #ifdef CONFIG_BUG | |
10 | static void handle_BUG(struct pt_regs *regs) | |
11 | { | |
12 | enum bug_trap_type tt; | |
13 | tt = report_bug(regs->pc, regs); | |
14 | if (tt == BUG_TRAP_TYPE_WARN) { | |
15 | regs->pc += instruction_size(regs->pc); | |
16 | return; | |
17 | } | |
18 | ||
19 | die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); | |
20 | } | |
21 | ||
22 | int is_valid_bugaddr(unsigned long addr) | |
23 | { | |
24 | return addr >= PAGE_OFFSET; | |
25 | } | |
26 | #endif | |
27 | ||
28 | /* | |
29 | * Generic trap handler. | |
30 | */ | |
31 | BUILD_TRAP_HANDLER(debug) | |
32 | { | |
33 | TRAP_HANDLER_DECL; | |
34 | ||
35 | /* Rewind */ | |
36 | regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); | |
37 | ||
38 | if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff, | |
39 | SIGTRAP) == NOTIFY_STOP) | |
40 | return; | |
41 | ||
42 | force_sig(SIGTRAP, current); | |
43 | } | |
44 | ||
45 | /* | |
46 | * Special handler for BUG() traps. | |
47 | */ | |
48 | BUILD_TRAP_HANDLER(bug) | |
49 | { | |
50 | TRAP_HANDLER_DECL; | |
51 | ||
52 | /* Rewind */ | |
53 | regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); | |
54 | ||
55 | if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff, | |
56 | SIGTRAP) == NOTIFY_STOP) | |
57 | return; | |
58 | ||
59 | #ifdef CONFIG_BUG | |
60 | if (__kernel_text_address(instruction_pointer(regs))) { | |
61 | opcode_t insn = *(opcode_t *)instruction_pointer(regs); | |
62 | if (insn == TRAPA_BUG_OPCODE) | |
63 | handle_BUG(regs); | |
64 | } | |
65 | #endif | |
66 | ||
67 | force_sig(SIGTRAP, current); | |
68 | } |