2 * linux/arch/arm/kernel/traps.c
4 * Copyright (C) 1995, 1996 Russell King
5 * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
9 * 'traps.c' handles hardware exceptions after we have saved some state in
10 * 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
11 * kill the offending process.
13 #include <linux/config.h>
14 #include <linux/types.h>
15 #include <linux/kernel.h>
16 #include <linux/signal.h>
17 #include <linux/sched.h>
19 #include <linux/spinlock.h>
21 #include <asm/system.h>
22 #include <asm/uaccess.h>
24 #include <asm/atomic.h>
25 #include <asm/pgtable.h>
27 extern void c_backtrace (unsigned long fp
, int pmode
);
28 extern int ptrace_cancel_bpt (struct task_struct
*);
30 char *processor_modes
[]=
31 { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
32 "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
33 "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
34 "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
37 static char *handler
[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
39 static inline void console_verbose(void)
41 extern int console_loglevel
;
42 console_loglevel
= 15;
45 int kstack_depth_to_print
= 200;
48 * Stack pointers should always be within the kernels view of
49 * physical memory. If it is not there, then we can't dump
50 * out any information relating to the stack.
52 static int verify_stack(unsigned long sp
)
54 if (sp
< PAGE_OFFSET
|| sp
> (unsigned long)high_memory
)
61 * Dump out the contents of some memory nicely...
63 void dump_mem(unsigned long bottom
, unsigned long top
)
65 unsigned long p
= bottom
& ~31;
68 for (p
= bottom
& ~31; p
< top
;) {
71 for (i
= 0; i
< 8; i
++, p
+= 4) {
72 if (p
< bottom
|| p
>= top
)
75 printk("%08lx ", *(unsigned long *)p
);
84 * These constants are for searching for possible module text
85 * segments. VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is
86 * a guess of how much space is likely to be vmalloced.
88 #define VMALLOC_OFFSET (8*1024*1024)
89 #define MODULE_RANGE (8*1024*1024)
91 static void dump_instr(unsigned long pc
, int user
)
93 int pmin
= -2, pmax
= 3, ok
= 0;
94 extern char start_kernel
, _etext
;
97 unsigned long module_start
, module_end
;
98 unsigned long kernel_start
, kernel_end
;
100 module_start
= VMALLOC_START
;
101 module_end
= module_start
+ MODULE_RANGE
;
103 kernel_start
= (unsigned long)&start_kernel
;
104 kernel_end
= (unsigned long)&_etext
;
106 if (pc
>= kernel_start
&& pc
< kernel_end
) {
107 if (pc
+ pmin
< kernel_start
)
108 pmin
= kernel_start
- pc
;
109 if (pc
+ pmax
> kernel_end
)
110 pmax
= kernel_end
- pc
;
112 } else if (pc
>= module_start
&& pc
< module_end
) {
113 if (pc
+ pmin
< module_start
)
114 pmin
= module_start
- pc
;
115 if (pc
+ pmax
> module_end
)
116 pmax
= module_end
- pc
;
120 ok
= verify_area(VERIFY_READ
, (void *)(pc
+ pmin
), pmax
- pmin
) == 0;
125 for (i
= pmin
; i
< pmax
; i
++)
126 printk(i
== 0 ? "(%08lx) " : "%08lx ", ((unsigned long *)pc
)[i
]);
129 printk ("pc not in code space\n");
135 * This function is protected against re-entrancy.
137 void die(const char *str
, struct pt_regs
*regs
, int err
)
139 struct task_struct
*tsk
= current
;
141 spin_lock_irq(&die_lock
);
144 printk("Internal error: %s: %x\n", str
, err
);
145 printk("CPU: %d\n", smp_processor_id());
147 printk("Process %s (pid: %d, stackpage=%08lx)\n",
148 current
->comm
, current
->pid
, 4096+(unsigned long)tsk
);
150 if (!user_mode(regs
)) {
151 unsigned long sp
= (unsigned long)(regs
+ 1);
156 if (verify_stack(sp
)) {
157 printk("invalid kernel stack pointer %08lx", sp
);
159 } else if (sp
< 4096+(unsigned long)tsk
)
160 printk("kernel stack pointer underflow");
164 dump_mem(sp
- 16, 8192+(unsigned long)tsk
);
168 printk("Backtrace: ");
171 printk("no frame pointer");
173 } else if (verify_stack(fp
)) {
174 printk("invalid frame pointer %08lx", fp
);
176 } else if (fp
< 4096+(unsigned long)tsk
)
177 printk("frame pointer underflow");
181 c_backtrace(fp
, processor_mode(regs
));
183 dump_instr(instruction_pointer(regs
), 0);
186 spin_unlock_irq(&die_lock
);
189 static void die_if_kernel(const char *str
, struct pt_regs
*regs
, int err
)
197 void bad_user_access_alignment(const void *ptr
)
199 printk(KERN_ERR
"bad user access alignment: ptr = %p, pc = %p\n", ptr
,
200 __builtin_return_address(0));
201 current
->thread
.error_code
= 0;
202 current
->thread
.trap_no
= 11;
203 force_sig(SIGBUS
, current
);
204 /* die_if_kernel("Oops - bad user access alignment", regs, mode);*/
207 asmlinkage
void do_undefinstr(int address
, struct pt_regs
*regs
, int mode
)
209 #ifdef CONFIG_DEBUG_USER
210 printk(KERN_INFO
"%s (%d): undefined instruction: pc=%08lx\n",
211 current
->comm
, current
->pid
, instruction_pointer(regs
));
213 current
->thread
.error_code
= 0;
214 current
->thread
.trap_no
= 6;
215 force_sig(SIGILL
, current
);
216 die_if_kernel("Oops - undefined instruction", regs
, mode
);
219 asmlinkage
void do_excpt(int address
, struct pt_regs
*regs
, int mode
)
221 #ifdef CONFIG_DEBUG_USER
222 printk(KERN_INFO
"%s (%d): address exception: pc=%08lx\n",
223 current
->comm
, current
->pid
, instruction_pointer(regs
));
225 current
->thread
.error_code
= 0;
226 current
->thread
.trap_no
= 11;
227 force_sig(SIGBUS
, current
);
228 die_if_kernel("Oops - address exception", regs
, mode
);
231 asmlinkage
void do_unexp_fiq (struct pt_regs
*regs
)
233 #ifndef CONFIG_IGNORE_FIQ
234 printk("Hmm. Unexpected FIQ received, but trying to continue\n");
235 printk("You may have a hardware problem...\n");
240 * bad_mode handles the impossible case in the vectors.
241 * If you see one of these, then it's extremely serious,
242 * and could mean you have buggy hardware. It never
243 * returns, and never tries to sync. We hope that we
244 * can dump out some state information...
246 asmlinkage
void bad_mode(struct pt_regs
*regs
, int reason
, int proc_mode
)
250 printk(KERN_CRIT
"Bad mode in %s handler detected: mode %s\n",
251 handler
[reason
], processor_modes
[proc_mode
]);
254 * Dump out the vectors and stub routines
256 printk(KERN_CRIT
"Vectors:\n");
258 printk(KERN_CRIT
"Stubs:\n");
259 dump_mem(0x200, 0x4b8);
261 die("Oops", regs
, 0);
267 * 'math_state_restore()' saves the current math information in the
268 * old math state array, and gets the new ones from the current task.
270 * We no longer save/restore the math state on every context switch
271 * any more. We only do this now if it actually gets used.
273 asmlinkage
void math_state_restore (void)
275 current
->used_math
= 1;
278 asmlinkage
int arm_syscall (int no
, struct pt_regs
*regs
)
281 case 0: /* branch through 0 */
282 force_sig(SIGSEGV
, current
);
283 die_if_kernel("branch through zero", regs
, 0);
286 case 1: /* SWI_BREAK_POINT */
287 regs
->ARM_pc
-= 4; /* Decrement PC by one instruction */
288 ptrace_cancel_bpt(current
);
289 force_sig(SIGTRAP
, current
);
292 case 2: /* sys_cacheflush */
294 /* r0 = start, r1 = length, r2 = flags */
295 cpu_flush_cache_area(regs
->ARM_r0
, regs
->ARM_r1
, 1);
300 /* Calls 9f00xx..9f07ff are defined to return -ENOSYS
301 if not implemented, rather than raising SIGILL. This
302 way the calling program can gracefully determine whether
303 a feature is supported. */
306 #ifdef CONFIG_DEBUG_USER
307 /* experiance shows that these seem to indicate that
308 * something catastrophic has happened
310 printk("[%d] %s: arm syscall %d\n", current
->pid
, current
->comm
, no
);
311 if (user_mode(regs
)) {
313 c_backtrace(regs
->ARM_fp
, processor_mode(regs
));
316 force_sig(SIGILL
, current
);
317 die_if_kernel("Oops", regs
, no
);
323 asmlinkage
void deferred(int n
, struct pt_regs
*regs
)
325 /* You might think just testing `handler' would be enough, but PER_LINUX
326 * points it to no_lcall7 to catch undercover SVr4 binaries. Gutted.
328 if (current
->personality
!= PER_LINUX
&& current
->exec_domain
->handler
) {
329 /* Hand it off to iBCS. The extra parameter and consequent type
330 * forcing is necessary because of the weird ARM calling convention.
332 void (*handler
)(int nr
, struct pt_regs
*regs
) = (void *)current
->exec_domain
->handler
;
337 #ifdef CONFIG_DEBUG_USER
338 printk(KERN_ERR
"[%d] %s: old system call.\n", current
->pid
,
341 force_sig(SIGILL
, current
);
344 asmlinkage
void arm_malalignedptr(const char *str
, void *pc
, volatile void *ptr
)
346 printk("Mal-aligned pointer in %s: %p (PC=%p)\n", str
, ptr
, pc
);
349 asmlinkage
void arm_invalidptr(const char *function
, int size
)
351 printk("Invalid pointer size in %s (pc=%p) size %d\n",
352 function
, __builtin_return_address(0), size
);
356 asmlinkage
void baddataabort(int code
, unsigned long instr
, struct pt_regs
*regs
)
358 unsigned long phys
, addr
= instruction_pointer(regs
);
360 #ifdef CONFIG_DEBUG_ERRORS
361 printk("pid=%d\n", current
->pid
);
364 dump_instr(instruction_pointer(regs
), 1);
368 printk ("current->thread.memmap = %08lX\n", current
->thread
.memmap
);
369 pgd
= pgd_offset(current
->mm
, addr
);
370 printk ("*pgd = %08lx", pgd_val (*pgd
));
371 if (!pgd_none (*pgd
)) {
373 pmd
= pmd_offset (pgd
, addr
);
374 printk (", *pmd = %08lx", pmd_val (*pmd
));
375 if (!pmd_none (*pmd
)) {
376 unsigned long ptr
= pte_page(*pte_offset(pmd
, addr
));
377 printk (", *pte = %08lx", pte_val (*pte_offset (pmd
, addr
)));
378 phys
= ptr
+ (addr
& 0x7fff);
384 panic("unknown data abort code %d [pc=%08lx *pc=%08lx lr=%08lx sp=%08lx]",
385 code
, regs
->ARM_pc
, instr
, regs
->ARM_lr
, regs
->ARM_sp
);
389 asmlinkage
void __div0(void)
391 printk("Awooga, division by zero in kernel.\n");