diff options
Diffstat (limited to 'arch/m68k/kernel/traps.c')
-rw-r--r-- | arch/m68k/kernel/traps.c | 60 |
1 files changed, 27 insertions, 33 deletions
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index 344f93d36a9a..53d0cf343d90 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -30,15 +30,19 @@ #include <linux/init.h> #include <linux/ptrace.h> #include <linux/kallsyms.h> +#include <linux/extable.h> #include <asm/setup.h> #include <asm/fpu.h> #include <linux/uaccess.h> #include <asm/traps.h> -#include <asm/pgalloc.h> #include <asm/machdep.h> +#include <asm/processor.h> #include <asm/siginfo.h> +#include <asm/tlbflush.h> +#include "traps.h" +#include "../mm/fault.h" static const char *vec_names[] = { [VEC_RESETSP] = "RESET SP", @@ -123,10 +127,6 @@ static const char *space_names[] = { }; void die_if_kernel(char *,struct pt_regs *,int); -asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code); -int send_fault_sig(struct pt_regs *regs); - asmlinkage void trap_c(struct frame *fp); #if defined (CONFIG_M68060) @@ -182,9 +182,8 @@ static inline void access_error060 (struct frame *fp) static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs) { unsigned long mmusr; - mm_segment_t old_fs = get_fs(); - set_fs(MAKE_MM_SEG(wbs)); + set_fc(wbs); if (iswrite) asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr)); @@ -193,7 +192,7 @@ static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs) asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr)); - set_fs(old_fs); + set_fc(USER_DATA); return mmusr; } @@ -202,10 +201,8 @@ static inline int do_040writeback1(unsigned short wbs, unsigned long wba, unsigned long wbd) { int res = 0; - mm_segment_t old_fs = get_fs(); - /* set_fs can not be moved, otherwise put_user() may oops */ - set_fs(MAKE_MM_SEG(wbs)); + set_fc(wbs); switch (wbs & WBSIZ_040) { case BA_SIZE_BYTE: @@ -219,9 +216,7 @@ static inline int do_040writeback1(unsigned short wbs, unsigned long wba, break; } - /* set_fs can not be moved, otherwise put_user() may oops */ - set_fs(old_fs); - + set_fc(USER_DATA); pr_debug("do_040writeback1, res=%d\n", res); @@ -369,7 +364,7 @@ disable_wb: #if defined(CONFIG_SUN3) #include <asm/sun3mmu.h> -extern int mmu_emu_handle_fault (unsigned long, int, int); +#include "../sun3/sun3.h" /* sun3 version of bus_error030 */ @@ -491,10 +486,10 @@ static inline void bus_error030 (struct frame *fp) if (buserr_type & SUN3_BUSERR_INVALID) { if (!mmu_emu_handle_fault(addr, 1, 0)) do_page_fault (&fp->ptregs, addr, 0); - } else { + } else { pr_debug("protection fault on insn access (segv).\n"); force_sig (SIGSEGV); - } + } } #else #if defined(CPU_M68020_OR_M68030) @@ -550,7 +545,8 @@ static inline void bus_error030 (struct frame *fp) errorcode |= 2; if (mmusr & (MMU_I | MMU_WP)) { - if (ssw & 4) { + /* We might have an exception table for this PC */ + if (ssw & 4 && !search_exception_tables(fp->ptregs.pc)) { pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n", ssw & RW ? "read" : "write", fp->un.fmtb.daddr, @@ -811,13 +807,13 @@ asmlinkage void buserr_c(struct frame *fp) static int kstack_depth_to_print = 48; -void show_trace(unsigned long *stack) +static void show_trace(unsigned long *stack, const char *loglvl) { unsigned long *endstack; unsigned long addr; int i; - pr_info("Call Trace:"); + printk("%sCall Trace:", loglvl); addr = (unsigned long)stack + THREAD_SIZE - 1; endstack = (unsigned long *)(addr & -THREAD_SIZE); i = 0; @@ -846,7 +842,6 @@ void show_trace(unsigned long *stack) void show_registers(struct pt_regs *regs) { struct frame *fp = (struct frame *)regs; - mm_segment_t old_fs = get_fs(); u16 c, *cp; unsigned long addr; int i; @@ -855,9 +850,9 @@ void show_registers(struct pt_regs *regs) pr_info("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc); pr_info("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2); pr_info("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", - regs->d0, regs->d1, regs->d2, regs->d3); + regs->d0, regs->d1, regs->d2, regs->d3); pr_info("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", - regs->d4, regs->d5, regs->a0, regs->a1); + regs->d4, regs->d5, regs->a0, regs->a1); pr_info("Process %s (pid: %d, task=%p)\n", current->comm, task_pid_nr(current), current); @@ -916,13 +911,12 @@ void show_registers(struct pt_regs *regs) default: pr_cont("\n"); } - show_stack(NULL, (unsigned long *)addr); + show_stack(NULL, (unsigned long *)addr, KERN_INFO); pr_info("Code:"); - set_fs(KERNEL_DS); cp = (u16 *)regs->pc; for (i = -8; i < 16; i++) { - if (get_user(c, cp + i) && i >= 0) { + if (get_kernel_nofault(c, cp + i) && i >= 0) { pr_cont(" Bad PC value."); break; } @@ -931,11 +925,11 @@ void show_registers(struct pt_regs *regs) else pr_cont(" <%04x>", c); } - set_fs(old_fs); pr_cont("\n"); } -void show_stack(struct task_struct *task, unsigned long *stack) +void show_stack(struct task_struct *task, unsigned long *stack, + const char *loglvl) { unsigned long *p; unsigned long *endstack; @@ -949,7 +943,7 @@ void show_stack(struct task_struct *task, unsigned long *stack) } endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE); - pr_info("Stack from %08lx:", (unsigned long)stack); + printk("%sStack from %08lx:", loglvl, (unsigned long)stack); p = stack; for (i = 0; i < kstack_depth_to_print; i++) { if (p + 1 > endstack) @@ -959,7 +953,7 @@ void show_stack(struct task_struct *task, unsigned long *stack) pr_cont(" %08lx", *p++); } pr_cont("\n"); - show_trace(stack); + show_trace(stack, loglvl); } /* @@ -970,7 +964,7 @@ void show_stack(struct task_struct *task, unsigned long *stack) * real 68k parts, but it won't hurt either. */ -void bad_super_trap (struct frame *fp) +static void bad_super_trap(struct frame *fp) { int vector = (fp->ptregs.vector >> 2) & 0xff; @@ -1139,7 +1133,7 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr) pr_crit("%s: %08x\n", str, nr); show_registers(fp); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } asmlinkage void set_esp0(unsigned long ssp) @@ -1153,7 +1147,7 @@ asmlinkage void set_esp0(unsigned long ssp) */ asmlinkage void fpsp040_die(void) { - do_exit(SIGSEGV); + force_exit_sig(SIGSEGV); } #ifdef CONFIG_M68KFPU_EMU |