summaryrefslogtreecommitdiff
path: root/arch/m68k/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/kernel/traps.c')
-rw-r--r--arch/m68k/kernel/traps.c60
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