.. | .. |
---|
30 | 30 | #include <linux/init.h> |
---|
31 | 31 | #include <linux/ptrace.h> |
---|
32 | 32 | #include <linux/kallsyms.h> |
---|
| 33 | +#include <linux/extable.h> |
---|
33 | 34 | |
---|
34 | 35 | #include <asm/setup.h> |
---|
35 | 36 | #include <asm/fpu.h> |
---|
36 | 37 | #include <linux/uaccess.h> |
---|
37 | 38 | #include <asm/traps.h> |
---|
38 | | -#include <asm/pgalloc.h> |
---|
39 | 39 | #include <asm/machdep.h> |
---|
40 | 40 | #include <asm/siginfo.h> |
---|
41 | | - |
---|
| 41 | +#include <asm/tlbflush.h> |
---|
42 | 42 | |
---|
43 | 43 | static const char *vec_names[] = { |
---|
44 | 44 | [VEC_RESETSP] = "RESET SP", |
---|
.. | .. |
---|
431 | 431 | pr_err("BAD KERNEL BUSERR\n"); |
---|
432 | 432 | |
---|
433 | 433 | die_if_kernel("Oops", &fp->ptregs,0); |
---|
434 | | - force_sig(SIGKILL, current); |
---|
| 434 | + force_sig(SIGKILL); |
---|
435 | 435 | return; |
---|
436 | 436 | } |
---|
437 | 437 | } else { |
---|
.. | .. |
---|
463 | 463 | !(ssw & RW) ? "write" : "read", addr, |
---|
464 | 464 | fp->ptregs.pc); |
---|
465 | 465 | die_if_kernel ("Oops", &fp->ptregs, buserr_type); |
---|
466 | | - force_sig (SIGBUS, current); |
---|
| 466 | + force_sig (SIGBUS); |
---|
467 | 467 | return; |
---|
468 | 468 | } |
---|
469 | 469 | |
---|
.. | .. |
---|
493 | 493 | do_page_fault (&fp->ptregs, addr, 0); |
---|
494 | 494 | } else { |
---|
495 | 495 | pr_debug("protection fault on insn access (segv).\n"); |
---|
496 | | - force_sig (SIGSEGV, current); |
---|
| 496 | + force_sig (SIGSEGV); |
---|
497 | 497 | } |
---|
498 | 498 | } |
---|
499 | 499 | #else |
---|
.. | .. |
---|
550 | 550 | errorcode |= 2; |
---|
551 | 551 | |
---|
552 | 552 | if (mmusr & (MMU_I | MMU_WP)) { |
---|
553 | | - if (ssw & 4) { |
---|
| 553 | + /* We might have an exception table for this PC */ |
---|
| 554 | + if (ssw & 4 && !search_exception_tables(fp->ptregs.pc)) { |
---|
554 | 555 | pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n", |
---|
555 | 556 | ssw & RW ? "read" : "write", |
---|
556 | 557 | fp->un.fmtb.daddr, |
---|
.. | .. |
---|
571 | 572 | !(ssw & RW) ? "write" : "read", addr, |
---|
572 | 573 | fp->ptregs.pc); |
---|
573 | 574 | die_if_kernel("Oops",&fp->ptregs,mmusr); |
---|
574 | | - force_sig(SIGSEGV, current); |
---|
| 575 | + force_sig(SIGSEGV); |
---|
575 | 576 | return; |
---|
576 | 577 | } else { |
---|
577 | 578 | #if 0 |
---|
.. | .. |
---|
598 | 599 | #endif |
---|
599 | 600 | pr_debug("Unknown SIGSEGV - 1\n"); |
---|
600 | 601 | die_if_kernel("Oops",&fp->ptregs,mmusr); |
---|
601 | | - force_sig(SIGSEGV, current); |
---|
| 602 | + force_sig(SIGSEGV); |
---|
602 | 603 | return; |
---|
603 | 604 | } |
---|
604 | 605 | |
---|
.. | .. |
---|
621 | 622 | buserr: |
---|
622 | 623 | pr_err("BAD KERNEL BUSERR\n"); |
---|
623 | 624 | die_if_kernel("Oops",&fp->ptregs,0); |
---|
624 | | - force_sig(SIGKILL, current); |
---|
| 625 | + force_sig(SIGKILL); |
---|
625 | 626 | return; |
---|
626 | 627 | } |
---|
627 | 628 | |
---|
.. | .. |
---|
660 | 661 | addr, fp->ptregs.pc); |
---|
661 | 662 | pr_debug("Unknown SIGSEGV - 2\n"); |
---|
662 | 663 | die_if_kernel("Oops",&fp->ptregs,mmusr); |
---|
663 | | - force_sig(SIGSEGV, current); |
---|
| 664 | + force_sig(SIGSEGV); |
---|
664 | 665 | return; |
---|
665 | 666 | } |
---|
666 | 667 | |
---|
.. | .. |
---|
804 | 805 | default: |
---|
805 | 806 | die_if_kernel("bad frame format",&fp->ptregs,0); |
---|
806 | 807 | pr_debug("Unknown SIGSEGV - 4\n"); |
---|
807 | | - force_sig(SIGSEGV, current); |
---|
| 808 | + force_sig(SIGSEGV); |
---|
808 | 809 | } |
---|
809 | 810 | } |
---|
810 | 811 | |
---|
811 | 812 | |
---|
812 | 813 | static int kstack_depth_to_print = 48; |
---|
813 | 814 | |
---|
814 | | -void show_trace(unsigned long *stack) |
---|
| 815 | +static void show_trace(unsigned long *stack, const char *loglvl) |
---|
815 | 816 | { |
---|
816 | 817 | unsigned long *endstack; |
---|
817 | 818 | unsigned long addr; |
---|
818 | 819 | int i; |
---|
819 | 820 | |
---|
820 | | - pr_info("Call Trace:"); |
---|
| 821 | + printk("%sCall Trace:", loglvl); |
---|
821 | 822 | addr = (unsigned long)stack + THREAD_SIZE - 1; |
---|
822 | 823 | endstack = (unsigned long *)(addr & -THREAD_SIZE); |
---|
823 | 824 | i = 0; |
---|
.. | .. |
---|
846 | 847 | void show_registers(struct pt_regs *regs) |
---|
847 | 848 | { |
---|
848 | 849 | struct frame *fp = (struct frame *)regs; |
---|
849 | | - mm_segment_t old_fs = get_fs(); |
---|
850 | 850 | u16 c, *cp; |
---|
851 | 851 | unsigned long addr; |
---|
852 | 852 | int i; |
---|
.. | .. |
---|
916 | 916 | default: |
---|
917 | 917 | pr_cont("\n"); |
---|
918 | 918 | } |
---|
919 | | - show_stack(NULL, (unsigned long *)addr); |
---|
| 919 | + show_stack(NULL, (unsigned long *)addr, KERN_INFO); |
---|
920 | 920 | |
---|
921 | 921 | pr_info("Code:"); |
---|
922 | | - set_fs(KERNEL_DS); |
---|
923 | 922 | cp = (u16 *)regs->pc; |
---|
924 | 923 | for (i = -8; i < 16; i++) { |
---|
925 | | - if (get_user(c, cp + i) && i >= 0) { |
---|
| 924 | + if (get_kernel_nofault(c, cp + i) && i >= 0) { |
---|
926 | 925 | pr_cont(" Bad PC value."); |
---|
927 | 926 | break; |
---|
928 | 927 | } |
---|
.. | .. |
---|
931 | 930 | else |
---|
932 | 931 | pr_cont(" <%04x>", c); |
---|
933 | 932 | } |
---|
934 | | - set_fs(old_fs); |
---|
935 | 933 | pr_cont("\n"); |
---|
936 | 934 | } |
---|
937 | 935 | |
---|
938 | | -void show_stack(struct task_struct *task, unsigned long *stack) |
---|
| 936 | +void show_stack(struct task_struct *task, unsigned long *stack, |
---|
| 937 | + const char *loglvl) |
---|
939 | 938 | { |
---|
940 | 939 | unsigned long *p; |
---|
941 | 940 | unsigned long *endstack; |
---|
.. | .. |
---|
949 | 948 | } |
---|
950 | 949 | endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE); |
---|
951 | 950 | |
---|
952 | | - pr_info("Stack from %08lx:", (unsigned long)stack); |
---|
| 951 | + printk("%sStack from %08lx:", loglvl, (unsigned long)stack); |
---|
953 | 952 | p = stack; |
---|
954 | 953 | for (i = 0; i < kstack_depth_to_print; i++) { |
---|
955 | 954 | if (p + 1 > endstack) |
---|
.. | .. |
---|
959 | 958 | pr_cont(" %08lx", *p++); |
---|
960 | 959 | } |
---|
961 | 960 | pr_cont("\n"); |
---|
962 | | - show_trace(stack); |
---|
| 961 | + show_trace(stack, loglvl); |
---|
963 | 962 | } |
---|
964 | 963 | |
---|
965 | 964 | /* |
---|
.. | .. |
---|
1127 | 1126 | addr = (void __user*) fp->un.fmtb.daddr; |
---|
1128 | 1127 | break; |
---|
1129 | 1128 | } |
---|
1130 | | - force_sig_fault(sig, si_code, addr, current); |
---|
| 1129 | + force_sig_fault(sig, si_code, addr); |
---|
1131 | 1130 | } |
---|
1132 | 1131 | |
---|
1133 | 1132 | void die_if_kernel (char *str, struct pt_regs *fp, int nr) |
---|
.. | .. |
---|
1139 | 1138 | pr_crit("%s: %08x\n", str, nr); |
---|
1140 | 1139 | show_registers(fp); |
---|
1141 | 1140 | add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); |
---|
1142 | | - do_exit(SIGSEGV); |
---|
| 1141 | + make_task_dead(SIGSEGV); |
---|
1143 | 1142 | } |
---|
1144 | 1143 | |
---|
1145 | 1144 | asmlinkage void set_esp0(unsigned long ssp) |
---|
.. | .. |
---|
1159 | 1158 | #ifdef CONFIG_M68KFPU_EMU |
---|
1160 | 1159 | asmlinkage void fpemu_signal(int signal, int code, void *addr) |
---|
1161 | 1160 | { |
---|
1162 | | - force_sig_fault(signal, code, addr, current); |
---|
| 1161 | + force_sig_fault(signal, code, addr); |
---|
1163 | 1162 | } |
---|
1164 | 1163 | #endif |
---|