Branch data Line data Source code
1 : : /*
2 : : * linux/arch/arm/kernel/traps.c
3 : : *
4 : : * Copyright (C) 1995-2009 Russell King
5 : : * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
6 : : *
7 : : * This program is free software; you can redistribute it and/or modify
8 : : * it under the terms of the GNU General Public License version 2 as
9 : : * published by the Free Software Foundation.
10 : : *
11 : : * 'traps.c' handles hardware exceptions after we have saved some state in
12 : : * 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
13 : : * kill the offending process.
14 : : */
15 : : #include <linux/signal.h>
16 : : #include <linux/personality.h>
17 : : #include <linux/kallsyms.h>
18 : : #include <linux/spinlock.h>
19 : : #include <linux/uaccess.h>
20 : : #include <linux/hardirq.h>
21 : : #include <linux/kdebug.h>
22 : : #include <linux/module.h>
23 : : #include <linux/kexec.h>
24 : : #include <linux/bug.h>
25 : : #include <linux/delay.h>
26 : : #include <linux/init.h>
27 : : #include <linux/sched.h>
28 : :
29 : : #include <linux/atomic.h>
30 : : #include <asm/cacheflush.h>
31 : : #include <asm/exception.h>
32 : : #include <asm/unistd.h>
33 : : #include <asm/traps.h>
34 : : #include <asm/unwind.h>
35 : : #include <asm/tls.h>
36 : : #include <asm/system_misc.h>
37 : : #include <asm/opcodes.h>
38 : :
39 : : static const char *handler[]= {
40 : : "prefetch abort",
41 : : "data abort",
42 : : "address exception",
43 : : "interrupt",
44 : : "undefined instruction",
45 : : };
46 : :
47 : : void *vectors_page;
48 : :
49 : : #ifdef CONFIG_DEBUG_USER
50 : : unsigned int user_debug;
51 : :
52 : : static int __init user_debug_setup(char *str)
53 : : {
54 : : get_option(&str, &user_debug);
55 : : return 1;
56 : : }
57 : : __setup("user_debug=", user_debug_setup);
58 : : #endif
59 : :
60 : : static void dump_mem(const char *, const char *, unsigned long, unsigned long);
61 : :
62 : 0 : void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
63 : : {
64 : : #ifdef CONFIG_KALLSYMS
65 : 40 : printk("[<%08lx>] (%ps) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
66 : : #else
67 : : printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
68 : : #endif
69 : :
70 [ # # ]: 40 : if (in_exception_text(where))
71 : 4 : dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
72 : 0 : }
73 : :
74 : : #ifndef CONFIG_ARM_UNWIND
75 : : /*
76 : : * Stack pointers should always be within the kernels view of
77 : : * physical memory. If it is not there, then we can't dump
78 : : * out any information relating to the stack.
79 : : */
80 : : static int verify_stack(unsigned long sp)
81 : : {
82 : : if (sp < PAGE_OFFSET ||
83 : : (sp > (unsigned long)high_memory && high_memory != NULL))
84 : : return -EFAULT;
85 : :
86 : : return 0;
87 : : }
88 : : #endif
89 : :
90 : : /*
91 : : * Dump out the contents of some memory nicely...
92 : : */
93 : 0 : static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
94 : : unsigned long top)
95 : : {
96 : : unsigned long first;
97 : : mm_segment_t fs;
98 : : int i;
99 : :
100 : : /*
101 : : * We need to switch to kernel mode so that we can use __get_user
102 : : * to safely read from kernel space. Note that we now dump the
103 : : * code first, just in case the backtrace kills us.
104 : : */
105 : 4 : fs = get_fs();
106 : : set_fs(KERNEL_DS);
107 : :
108 : 4 : printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top);
109 : :
110 [ + + ]: 16 : for (first = bottom & ~31; first < top; first += 32) {
111 : : unsigned long p;
112 : : char str[sizeof(" 12345678") * 8 + 1];
113 : :
114 : 12 : memset(str, ' ', sizeof(str));
115 : 12 : str[sizeof(str) - 1] = '\0';
116 : :
117 [ + + ]: 100 : for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
118 [ + + ]: 88 : if (p >= bottom && p < top) {
119 : : unsigned long val;
120 [ + - ]: 72 : if (__get_user(val, (unsigned long *)p) == 0)
121 : 72 : sprintf(str + i * 9, " %08lx", val);
122 : : else
123 : 0 : sprintf(str + i * 9, " ????????");
124 : : }
125 : : }
126 : 12 : printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
127 : : }
128 : :
129 : : set_fs(fs);
130 : 4 : }
131 : :
132 : 0 : static void dump_instr(const char *lvl, struct pt_regs *regs)
133 : : {
134 : 0 : unsigned long addr = instruction_pointer(regs);
135 : 0 : const int thumb = thumb_mode(regs);
136 [ # # ]: 0 : const int width = thumb ? 4 : 8;
137 : : mm_segment_t fs;
138 : : char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
139 : : int i;
140 : :
141 : : /*
142 : : * We need to switch to kernel mode so that we can use __get_user
143 : : * to safely read from kernel space. Note that we now dump the
144 : : * code first, just in case the backtrace kills us.
145 : : */
146 : 0 : fs = get_fs();
147 : : set_fs(KERNEL_DS);
148 : :
149 [ # # ][ # # ]: 0 : for (i = -4; i < 1 + !!thumb; i++) {
150 : : unsigned int val, bad;
151 : :
152 [ # # ]: 0 : if (thumb)
153 : 0 : bad = __get_user(val, &((u16 *)addr)[i]);
154 : : else
155 : 0 : bad = __get_user(val, &((u32 *)addr)[i]);
156 : :
157 [ # # ]: 0 : if (!bad)
158 [ # # ]: 0 : p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
159 : : width, val);
160 : : else {
161 : 0 : p += sprintf(p, "bad PC value");
162 : : break;
163 : : }
164 : : }
165 : 0 : printk("%sCode: %s\n", lvl, str);
166 : :
167 : : set_fs(fs);
168 : 0 : }
169 : :
170 : : #ifdef CONFIG_ARM_UNWIND
171 : : static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
172 : : {
173 : 4 : unwind_backtrace(regs, tsk);
174 : : }
175 : : #else
176 : : static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
177 : : {
178 : : unsigned int fp, mode;
179 : : int ok = 1;
180 : :
181 : : printk("Backtrace: ");
182 : :
183 : : if (!tsk)
184 : : tsk = current;
185 : :
186 : : if (regs) {
187 : : fp = regs->ARM_fp;
188 : : mode = processor_mode(regs);
189 : : } else if (tsk != current) {
190 : : fp = thread_saved_fp(tsk);
191 : : mode = 0x10;
192 : : } else {
193 : : asm("mov %0, fp" : "=r" (fp) : : "cc");
194 : : mode = 0x10;
195 : : }
196 : :
197 : : if (!fp) {
198 : : printk("no frame pointer");
199 : : ok = 0;
200 : : } else if (verify_stack(fp)) {
201 : : printk("invalid frame pointer 0x%08x", fp);
202 : : ok = 0;
203 : : } else if (fp < (unsigned long)end_of_stack(tsk))
204 : : printk("frame pointer underflow");
205 : : printk("\n");
206 : :
207 : : if (ok)
208 : : c_backtrace(fp, mode);
209 : : }
210 : : #endif
211 : :
212 : 0 : void show_stack(struct task_struct *tsk, unsigned long *sp)
213 : : {
214 : : dump_backtrace(NULL, tsk);
215 : 4 : barrier();
216 : 4 : }
217 : :
218 : : #ifdef CONFIG_PREEMPT
219 : : #define S_PREEMPT " PREEMPT"
220 : : #else
221 : : #define S_PREEMPT ""
222 : : #endif
223 : : #ifdef CONFIG_SMP
224 : : #define S_SMP " SMP"
225 : : #else
226 : : #define S_SMP ""
227 : : #endif
228 : : #ifdef CONFIG_THUMB2_KERNEL
229 : : #define S_ISA " THUMB2"
230 : : #else
231 : : #define S_ISA " ARM"
232 : : #endif
233 : :
234 : 0 : static int __die(const char *str, int err, struct pt_regs *regs)
235 : : {
236 : 0 : struct task_struct *tsk = current;
237 : : static int die_counter;
238 : : int ret;
239 : :
240 : 0 : printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP
241 : : S_ISA "\n", str, err, ++die_counter);
242 : :
243 : : /* trap and error numbers are mostly meaningless on ARM */
244 : 0 : ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
245 [ # # ]: 0 : if (ret == NOTIFY_STOP)
246 : : return 1;
247 : :
248 : 0 : print_modules();
249 : 0 : __show_regs(regs);
250 : 0 : printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
251 : 0 : TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk));
252 : :
253 [ # # ][ # # ]: 0 : if (!user_mode(regs) || in_interrupt()) {
254 : 0 : dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
255 : 0 : THREAD_SIZE + (unsigned long)task_stack_page(tsk));
256 : : dump_backtrace(regs, tsk);
257 : 0 : dump_instr(KERN_EMERG, regs);
258 : : }
259 : :
260 : : return 0;
261 : : }
262 : :
263 : : static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
264 : : static int die_owner = -1;
265 : : static unsigned int die_nest_count;
266 : :
267 : 0 : static unsigned long oops_begin(void)
268 : : {
269 : : int cpu;
270 : : unsigned long flags;
271 : :
272 : 0 : oops_enter();
273 : :
274 : : /* racy, but better than risking deadlock. */
275 : : raw_local_irq_save(flags);
276 : 0 : cpu = smp_processor_id();
277 [ # # ]: 0 : if (!arch_spin_trylock(&die_lock)) {
278 [ # # ]: 0 : if (cpu == die_owner)
279 : : /* nested oops. should stop eventually */;
280 : : else
281 : : arch_spin_lock(&die_lock);
282 : : }
283 : 0 : die_nest_count++;
284 : 0 : die_owner = cpu;
285 : : console_verbose();
286 : 0 : bust_spinlocks(1);
287 : 0 : return flags;
288 : : }
289 : :
290 : 0 : static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
291 : : {
292 : : if (regs && kexec_should_crash(current))
293 : : crash_kexec(regs);
294 : :
295 : 0 : bust_spinlocks(0);
296 : 0 : die_owner = -1;
297 : 0 : add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
298 : 0 : die_nest_count--;
299 [ # # ]: 0 : if (!die_nest_count)
300 : : /* Nest count reaches zero, release the lock. */
301 : : arch_spin_unlock(&die_lock);
302 : : raw_local_irq_restore(flags);
303 : 0 : oops_exit();
304 : :
305 [ # # ]: 0 : if (in_interrupt())
306 : 0 : panic("Fatal exception in interrupt");
307 [ # # ]: 0 : if (panic_on_oops)
308 : 0 : panic("Fatal exception");
309 [ # # ]: 0 : if (signr)
310 : 0 : do_exit(signr);
311 : 0 : }
312 : :
313 : : /*
314 : : * This function is protected against re-entrancy.
315 : : */
316 : 0 : void die(const char *str, struct pt_regs *regs, int err)
317 : : {
318 : : enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE;
319 : 0 : unsigned long flags = oops_begin();
320 : : int sig = SIGSEGV;
321 : :
322 [ # # ]: 0 : if (!user_mode(regs))
323 : 0 : bug_type = report_bug(regs->ARM_pc, regs);
324 [ # # ]: 0 : if (bug_type != BUG_TRAP_TYPE_NONE)
325 : : str = "Oops - BUG";
326 : :
327 [ # # ]: 0 : if (__die(str, err, regs))
328 : : sig = 0;
329 : :
330 : 0 : oops_end(flags, regs, sig);
331 : 0 : }
332 : :
333 : 0 : void arm_notify_die(const char *str, struct pt_regs *regs,
334 : : struct siginfo *info, unsigned long err, unsigned long trap)
335 : : {
336 [ # # ]: 0 : if (user_mode(regs)) {
337 : 0 : current->thread.error_code = err;
338 : 0 : current->thread.trap_no = trap;
339 : :
340 : 0 : force_sig_info(info->si_signo, info, current);
341 : : } else {
342 : 0 : die(str, regs, err);
343 : : }
344 : 0 : }
345 : :
346 : : #ifdef CONFIG_GENERIC_BUG
347 : :
348 : 0 : int is_valid_bugaddr(unsigned long pc)
349 : : {
350 : : #ifdef CONFIG_THUMB2_KERNEL
351 : : u16 bkpt;
352 : : u16 insn = __opcode_to_mem_thumb16(BUG_INSTR_VALUE);
353 : : #else
354 : : u32 bkpt;
355 : : u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE);
356 : : #endif
357 : :
358 [ # # ]: 0 : if (probe_kernel_address((unsigned *)pc, bkpt))
359 : : return 0;
360 : :
361 : 0 : return bkpt == insn;
362 : : }
363 : :
364 : : #endif
365 : :
366 : : static LIST_HEAD(undef_hook);
367 : : static DEFINE_RAW_SPINLOCK(undef_lock);
368 : :
369 : 0 : void register_undef_hook(struct undef_hook *hook)
370 : : {
371 : : unsigned long flags;
372 : :
373 : 0 : raw_spin_lock_irqsave(&undef_lock, flags);
374 : 0 : list_add(&hook->node, &undef_hook);
375 : 0 : raw_spin_unlock_irqrestore(&undef_lock, flags);
376 : 0 : }
377 : :
378 : 0 : void unregister_undef_hook(struct undef_hook *hook)
379 : : {
380 : : unsigned long flags;
381 : :
382 : 0 : raw_spin_lock_irqsave(&undef_lock, flags);
383 : : list_del(&hook->node);
384 : 0 : raw_spin_unlock_irqrestore(&undef_lock, flags);
385 : 0 : }
386 : :
387 : 0 : static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
388 : : {
389 : : struct undef_hook *hook;
390 : : unsigned long flags;
391 : : int (*fn)(struct pt_regs *regs, unsigned int instr) = NULL;
392 : :
393 : 0 : raw_spin_lock_irqsave(&undef_lock, flags);
394 [ # # ]: 0 : list_for_each_entry(hook, &undef_hook, node)
395 [ # # ][ # # ]: 0 : if ((instr & hook->instr_mask) == hook->instr_val &&
396 : 0 : (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val)
397 : 0 : fn = hook->fn;
398 : 0 : raw_spin_unlock_irqrestore(&undef_lock, flags);
399 : :
400 [ # # ]: 0 : return fn ? fn(regs, instr) : 1;
401 : : }
402 : :
403 : 0 : asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
404 : : {
405 : : unsigned int instr;
406 : : siginfo_t info;
407 : : void __user *pc;
408 : :
409 : 0 : pc = (void __user *)instruction_pointer(regs);
410 : :
411 [ # # ]: 0 : if (processor_mode(regs) == SVC_MODE) {
412 : : #ifdef CONFIG_THUMB2_KERNEL
413 [ # # ]: 0 : if (thumb_mode(regs)) {
414 : 0 : instr = __mem_to_opcode_thumb16(((u16 *)pc)[0]);
415 [ # # ]: 0 : if (is_wide_instruction(instr)) {
416 : : u16 inst2;
417 : 0 : inst2 = __mem_to_opcode_thumb16(((u16 *)pc)[1]);
418 : 0 : instr = __opcode_thumb32_compose(instr, inst2);
419 : : }
420 : : } else
421 : : #endif
422 : 0 : instr = __mem_to_opcode_arm(*(u32 *) pc);
423 [ # # ]: 0 : } else if (thumb_mode(regs)) {
424 [ # # ]: 0 : if (get_user(instr, (u16 __user *)pc))
425 : : goto die_sig;
426 : : instr = __mem_to_opcode_thumb16(instr);
427 [ # # ]: 0 : if (is_wide_instruction(instr)) {
428 : : unsigned int instr2;
429 [ # # ]: 0 : if (get_user(instr2, (u16 __user *)pc+1))
430 : : goto die_sig;
431 : : instr2 = __mem_to_opcode_thumb16(instr2);
432 : 0 : instr = __opcode_thumb32_compose(instr, instr2);
433 : : }
434 : : } else {
435 [ # # ]: 0 : if (get_user(instr, (u32 __user *)pc))
436 : : goto die_sig;
437 : : instr = __mem_to_opcode_arm(instr);
438 : : }
439 : :
440 [ # # ]: 0 : if (call_undef_hook(regs, instr) == 0)
441 : 0 : return;
442 : :
443 : : die_sig:
444 : : #ifdef CONFIG_DEBUG_USER
445 : : if (user_debug & UDBG_UNDEFINED) {
446 : : printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
447 : : current->comm, task_pid_nr(current), pc);
448 : : dump_instr(KERN_INFO, regs);
449 : : }
450 : : #endif
451 : :
452 : 0 : info.si_signo = SIGILL;
453 : 0 : info.si_errno = 0;
454 : 0 : info.si_code = ILL_ILLOPC;
455 : 0 : info.si_addr = pc;
456 : :
457 : 0 : arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
458 : : }
459 : :
460 : 0 : asmlinkage void do_unexp_fiq (struct pt_regs *regs)
461 : : {
462 : 0 : printk("Hmm. Unexpected FIQ received, but trying to continue\n");
463 : 0 : printk("You may have a hardware problem...\n");
464 : 0 : }
465 : :
466 : : /*
467 : : * bad_mode handles the impossible case in the vectors. If you see one of
468 : : * these, then it's extremely serious, and could mean you have buggy hardware.
469 : : * It never returns, and never tries to sync. We hope that we can at least
470 : : * dump out some state information...
471 : : */
472 : 0 : asmlinkage void bad_mode(struct pt_regs *regs, int reason)
473 : : {
474 : : console_verbose();
475 : :
476 : 0 : printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]);
477 : :
478 : 0 : die("Oops - bad mode", regs, 0);
479 : : local_irq_disable();
480 : 0 : panic("bad mode");
481 : : }
482 : :
483 : 0 : static int bad_syscall(int n, struct pt_regs *regs)
484 : : {
485 : : struct thread_info *thread = current_thread_info();
486 : : siginfo_t info;
487 : :
488 [ # # ][ # # ]: 0 : if ((current->personality & PER_MASK) != PER_LINUX &&
489 : 0 : thread->exec_domain->handler) {
490 : 0 : thread->exec_domain->handler(n, regs);
491 : 0 : return regs->ARM_r0;
492 : : }
493 : :
494 : : #ifdef CONFIG_DEBUG_USER
495 : : if (user_debug & UDBG_SYSCALL) {
496 : : printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
497 : : task_pid_nr(current), current->comm, n);
498 : : dump_instr(KERN_ERR, regs);
499 : : }
500 : : #endif
501 : :
502 : 0 : info.si_signo = SIGILL;
503 : 0 : info.si_errno = 0;
504 : 0 : info.si_code = ILL_ILLTRP;
505 [ # # ]: 0 : info.si_addr = (void __user *)instruction_pointer(regs) -
506 : 0 : (thumb_mode(regs) ? 2 : 4);
507 : :
508 : 0 : arm_notify_die("Oops - bad syscall", regs, &info, n, 0);
509 : :
510 : 0 : return regs->ARM_r0;
511 : : }
512 : :
513 : : static long do_cache_op_restart(struct restart_block *);
514 : :
515 : : static inline int
516 : : __do_cache_op(unsigned long start, unsigned long end)
517 : : {
518 : : int ret;
519 : :
520 : : do {
521 : 0 : unsigned long chunk = min(PAGE_SIZE, end - start);
522 : :
523 [ # # ][ # # ]: 0 : if (signal_pending(current)) {
524 : : struct thread_info *ti = current_thread_info();
525 : :
526 : 0 : ti->restart_block = (struct restart_block) {
527 : : .fn = do_cache_op_restart,
528 : : };
529 : :
530 : 0 : ti->arm_restart_block = (struct arm_restart_block) {
531 : : {
532 : : .cache = {
533 : : .start = start,
534 : : .end = end,
535 : : },
536 : : },
537 : : };
538 : :
539 : : return -ERESTART_RESTARTBLOCK;
540 : : }
541 : :
542 : 0 : ret = flush_cache_user_range(start, start + chunk);
543 [ # # # # ]: 0 : if (ret)
544 : : return ret;
545 : :
546 : 0 : cond_resched();
547 : : start += chunk;
548 [ # # # # ]: 0 : } while (start < end);
549 : :
550 : : return 0;
551 : : }
552 : :
553 : 0 : static long do_cache_op_restart(struct restart_block *unused)
554 : : {
555 : : struct arm_restart_block *restart_block;
556 : :
557 : : restart_block = ¤t_thread_info()->arm_restart_block;
558 : 0 : return __do_cache_op(restart_block->cache.start,
559 : : restart_block->cache.end);
560 : : }
561 : :
562 : : static inline int
563 : : do_cache_op(unsigned long start, unsigned long end, int flags)
564 : : {
565 [ # # ]: 0 : if (end < start || flags)
566 : : return -EINVAL;
567 : :
568 [ # # ]: 0 : if (!access_ok(VERIFY_READ, start, end - start))
569 : : return -EFAULT;
570 : :
571 : : return __do_cache_op(start, end);
572 : : }
573 : :
574 : : /*
575 : : * Handle all unrecognised system calls.
576 : : * 0x9f0000 - 0x9fffff are some more esoteric system calls
577 : : */
578 : : #define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE)
579 : 0 : asmlinkage int arm_syscall(int no, struct pt_regs *regs)
580 : : {
581 : : struct thread_info *thread = current_thread_info();
582 : : siginfo_t info;
583 : :
584 [ - + ]: 27245 : if ((no >> 16) != (__ARM_NR_BASE>> 16))
585 : 0 : return bad_syscall(no, regs);
586 : :
587 [ - - - - : 27245 : switch (no & 0xffff) {
- + - ]
588 : : case 0: /* branch through 0 */
589 : 0 : info.si_signo = SIGSEGV;
590 : 0 : info.si_errno = 0;
591 : 0 : info.si_code = SEGV_MAPERR;
592 : 0 : info.si_addr = NULL;
593 : :
594 : 0 : arm_notify_die("branch through zero", regs, &info, 0, 0);
595 : 0 : return 0;
596 : :
597 : : case NR(breakpoint): /* SWI BREAK_POINT */
598 [ # # ]: 0 : regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
599 : 0 : ptrace_break(current, regs);
600 : 0 : return regs->ARM_r0;
601 : :
602 : : /*
603 : : * Flush a region from virtual address 'r0' to virtual address 'r1'
604 : : * _exclusive_. There is no alignment requirement on either address;
605 : : * user space does not need to know the hardware cache layout.
606 : : *
607 : : * r2 contains flags. It should ALWAYS be passed as ZERO until it
608 : : * is defined to be something else. For now we ignore it, but may
609 : : * the fires of hell burn in your belly if you break this rule. ;)
610 : : *
611 : : * (at a later date, we may want to allow this call to not flush
612 : : * various aspects of the cache. Passing '0' will guarantee that
613 : : * everything necessary gets flushed to maintain consistency in
614 : : * the specified region).
615 : : */
616 : : case NR(cacheflush):
617 : 0 : return do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2);
618 : :
619 : : case NR(usr26):
620 [ # # ]: 0 : if (!(elf_hwcap & HWCAP_26BIT))
621 : : break;
622 : 0 : regs->ARM_cpsr &= ~MODE32_BIT;
623 : 0 : return regs->ARM_r0;
624 : :
625 : : case NR(usr32):
626 [ # # ]: 0 : if (!(elf_hwcap & HWCAP_26BIT))
627 : : break;
628 : 0 : regs->ARM_cpsr |= MODE32_BIT;
629 : 0 : return regs->ARM_r0;
630 : :
631 : : case NR(set_tls):
632 : 27245 : thread->tp_value[0] = regs->ARM_r0;
633 : : if (tls_emu)
634 : : return 0;
635 : : if (has_tls_reg) {
636 : 27245 : asm ("mcr p15, 0, %0, c13, c0, 3"
637 : 27245 : : : "r" (regs->ARM_r0));
638 : : } else {
639 : : /*
640 : : * User space must never try to access this directly.
641 : : * Expect your app to break eventually if you do so.
642 : : * The user helper at 0xffff0fe0 must be used instead.
643 : : * (see entry-armv.S for details)
644 : : */
645 : : *((unsigned int *)0xffff0ff0) = regs->ARM_r0;
646 : : }
647 : 27244 : return 0;
648 : :
649 : : #ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
650 : : /*
651 : : * Atomically store r1 in *r2 if *r2 is equal to r0 for user space.
652 : : * Return zero in r0 if *MEM was changed or non-zero if no exchange
653 : : * happened. Also set the user C flag accordingly.
654 : : * If access permissions have to be fixed up then non-zero is
655 : : * returned and the operation has to be re-attempted.
656 : : *
657 : : * *NOTE*: This is a ghost syscall private to the kernel. Only the
658 : : * __kuser_cmpxchg code in entry-armv.S should be aware of its
659 : : * existence. Don't ever use this from user code.
660 : : */
661 : : case NR(cmpxchg):
662 : : for (;;) {
663 : : extern void do_DataAbort(unsigned long addr, unsigned int fsr,
664 : : struct pt_regs *regs);
665 : : unsigned long val;
666 : : unsigned long addr = regs->ARM_r2;
667 : : struct mm_struct *mm = current->mm;
668 : : pgd_t *pgd; pmd_t *pmd; pte_t *pte;
669 : : spinlock_t *ptl;
670 : :
671 : : regs->ARM_cpsr &= ~PSR_C_BIT;
672 : : down_read(&mm->mmap_sem);
673 : : pgd = pgd_offset(mm, addr);
674 : : if (!pgd_present(*pgd))
675 : : goto bad_access;
676 : : pmd = pmd_offset(pgd, addr);
677 : : if (!pmd_present(*pmd))
678 : : goto bad_access;
679 : : pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
680 : : if (!pte_present(*pte) || !pte_write(*pte) || !pte_dirty(*pte)) {
681 : : pte_unmap_unlock(pte, ptl);
682 : : goto bad_access;
683 : : }
684 : : val = *(unsigned long *)addr;
685 : : val -= regs->ARM_r0;
686 : : if (val == 0) {
687 : : *(unsigned long *)addr = regs->ARM_r1;
688 : : regs->ARM_cpsr |= PSR_C_BIT;
689 : : }
690 : : pte_unmap_unlock(pte, ptl);
691 : : up_read(&mm->mmap_sem);
692 : : return val;
693 : :
694 : : bad_access:
695 : : up_read(&mm->mmap_sem);
696 : : /* simulate a write access fault */
697 : : do_DataAbort(addr, 15 + (1 << 11), regs);
698 : : }
699 : : #endif
700 : :
701 : : default:
702 : : /* Calls 9f00xx..9f07ff are defined to return -ENOSYS
703 : : if not implemented, rather than raising SIGILL. This
704 : : way the calling program can gracefully determine whether
705 : : a feature is supported. */
706 [ # # ]: 0 : if ((no & 0xffff) <= 0x7ff)
707 : : return -ENOSYS;
708 : : break;
709 : : }
710 : : #ifdef CONFIG_DEBUG_USER
711 : : /*
712 : : * experience shows that these seem to indicate that
713 : : * something catastrophic has happened
714 : : */
715 : : if (user_debug & UDBG_SYSCALL) {
716 : : printk("[%d] %s: arm syscall %d\n",
717 : : task_pid_nr(current), current->comm, no);
718 : : dump_instr("", regs);
719 : : if (user_mode(regs)) {
720 : : __show_regs(regs);
721 : : c_backtrace(regs->ARM_fp, processor_mode(regs));
722 : : }
723 : : }
724 : : #endif
725 : 0 : info.si_signo = SIGILL;
726 : 0 : info.si_errno = 0;
727 : 0 : info.si_code = ILL_ILLTRP;
728 [ # # ]: 0 : info.si_addr = (void __user *)instruction_pointer(regs) -
729 : 0 : (thumb_mode(regs) ? 2 : 4);
730 : :
731 : 0 : arm_notify_die("Oops - bad syscall(2)", regs, &info, no, 0);
732 : 0 : return 0;
733 : : }
734 : :
735 : : #ifdef CONFIG_TLS_REG_EMUL
736 : :
737 : : /*
738 : : * We might be running on an ARMv6+ processor which should have the TLS
739 : : * register but for some reason we can't use it, or maybe an SMP system
740 : : * using a pre-ARMv6 processor (there are apparently a few prototypes like
741 : : * that in existence) and therefore access to that register must be
742 : : * emulated.
743 : : */
744 : :
745 : : static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
746 : : {
747 : : int reg = (instr >> 12) & 15;
748 : : if (reg == 15)
749 : : return 1;
750 : : regs->uregs[reg] = current_thread_info()->tp_value[0];
751 : : regs->ARM_pc += 4;
752 : : return 0;
753 : : }
754 : :
755 : : static struct undef_hook arm_mrc_hook = {
756 : : .instr_mask = 0x0fff0fff,
757 : : .instr_val = 0x0e1d0f70,
758 : : .cpsr_mask = PSR_T_BIT,
759 : : .cpsr_val = 0,
760 : : .fn = get_tp_trap,
761 : : };
762 : :
763 : : static int __init arm_mrc_hook_init(void)
764 : : {
765 : : register_undef_hook(&arm_mrc_hook);
766 : : return 0;
767 : : }
768 : :
769 : : late_initcall(arm_mrc_hook_init);
770 : :
771 : : #endif
772 : :
773 : 0 : void __bad_xchg(volatile void *ptr, int size)
774 : : {
775 : 0 : printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
776 : : __builtin_return_address(0), ptr, size);
777 : 0 : BUG();
778 : : }
779 : : EXPORT_SYMBOL(__bad_xchg);
780 : :
781 : : /*
782 : : * A data abort trap was taken, but we did not handle the instruction.
783 : : * Try to abort the user program, or panic if it was the kernel.
784 : : */
785 : : asmlinkage void
786 : 0 : baddataabort(int code, unsigned long instr, struct pt_regs *regs)
787 : : {
788 : 0 : unsigned long addr = instruction_pointer(regs);
789 : : siginfo_t info;
790 : :
791 : : #ifdef CONFIG_DEBUG_USER
792 : : if (user_debug & UDBG_BADABORT) {
793 : : printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
794 : : task_pid_nr(current), current->comm, code, instr);
795 : : dump_instr(KERN_ERR, regs);
796 : : show_pte(current->mm, addr);
797 : : }
798 : : #endif
799 : :
800 : 0 : info.si_signo = SIGILL;
801 : 0 : info.si_errno = 0;
802 : 0 : info.si_code = ILL_ILLOPC;
803 : 0 : info.si_addr = (void __user *)addr;
804 : :
805 : 0 : arm_notify_die("unknown data abort code", regs, &info, instr, 0);
806 : 0 : }
807 : :
808 : 0 : void __readwrite_bug(const char *fn)
809 : : {
810 : 0 : printk("%s called, but not implemented\n", fn);
811 : 0 : BUG();
812 : : }
813 : : EXPORT_SYMBOL(__readwrite_bug);
814 : :
815 : 0 : void __pte_error(const char *file, int line, pte_t pte)
816 : : {
817 : 0 : printk("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte));
818 : 0 : }
819 : :
820 : 0 : void __pmd_error(const char *file, int line, pmd_t pmd)
821 : : {
822 : 0 : printk("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd));
823 : 0 : }
824 : :
825 : 0 : void __pgd_error(const char *file, int line, pgd_t pgd)
826 : : {
827 : 0 : printk("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd));
828 : 0 : }
829 : :
830 : 0 : asmlinkage void __div0(void)
831 : : {
832 : 0 : printk("Division by zero in kernel.\n");
833 : 0 : dump_stack();
834 : 0 : }
835 : : EXPORT_SYMBOL(__div0);
836 : :
837 : 0 : void abort(void)
838 : : {
839 : 0 : BUG();
840 : :
841 : : /* if that doesn't kill us, halt */
842 : : panic("Oops failed to kill thread");
843 : : }
844 : : EXPORT_SYMBOL(abort);
845 : :
846 : 0 : void __init trap_init(void)
847 : : {
848 : 0 : return;
849 : : }
850 : :
851 : : #ifdef CONFIG_KUSER_HELPERS
852 : 0 : static void __init kuser_init(void *vectors)
853 : : {
854 : : extern char __kuser_helper_start[], __kuser_helper_end[];
855 : 0 : int kuser_sz = __kuser_helper_end - __kuser_helper_start;
856 : :
857 : 0 : memcpy(vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
858 : :
859 : : /*
860 : : * vectors + 0xfe0 = __kuser_get_tls
861 : : * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
862 : : */
863 : : if (tls_emu || has_tls_reg)
864 : 0 : memcpy(vectors + 0xfe0, vectors + 0xfe8, 4);
865 : 0 : }
866 : : #else
867 : : static inline void __init kuser_init(void *vectors)
868 : : {
869 : : }
870 : : #endif
871 : :
872 : 0 : void __init early_trap_init(void *vectors_base)
873 : : {
874 : : #ifndef CONFIG_CPU_V7M
875 : 0 : unsigned long vectors = (unsigned long)vectors_base;
876 : : extern char __stubs_start[], __stubs_end[];
877 : : extern char __vectors_start[], __vectors_end[];
878 : : unsigned i;
879 : :
880 : 0 : vectors_page = vectors_base;
881 : :
882 : : /*
883 : : * Poison the vectors page with an undefined instruction. This
884 : : * instruction is chosen to be undefined for both ARM and Thumb
885 : : * ISAs. The Thumb version is an undefined instruction with a
886 : : * branch back to the undefined instruction.
887 : : */
888 [ # # ]: 0 : for (i = 0; i < PAGE_SIZE / sizeof(u32); i++)
889 : 0 : ((u32 *)vectors_base)[i] = 0xe7fddef1;
890 : :
891 : : /*
892 : : * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
893 : : * into the vector page, mapped at 0xffff0000, and ensure these
894 : : * are visible to the instruction stream.
895 : : */
896 : 0 : memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
897 : 0 : memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
898 : :
899 : 0 : kuser_init(vectors_base);
900 : :
901 : 0 : flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
902 : : modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
903 : : #else /* ifndef CONFIG_CPU_V7M */
904 : : /*
905 : : * on V7-M there is no need to copy the vector table to a dedicated
906 : : * memory area. The address is configurable and so a table in the kernel
907 : : * image can be used.
908 : : */
909 : : #endif
910 : 0 : }
|