diff options
Diffstat (limited to 'arch/m68k/kernel')
-rw-r--r-- | arch/m68k/kernel/setup.c | 5 | ||||
-rw-r--r-- | arch/m68k/kernel/signal.c | 24 | ||||
-rw-r--r-- | arch/m68k/kernel/traps.c | 20 |
3 files changed, 40 insertions, 9 deletions
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index b3963ab3d14..334d8364037 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -42,6 +42,7 @@ #ifdef CONFIG_SUN3X #include <asm/dvma.h> #endif +#include <asm/natfeat.h> #if !FPSTATESIZE || !NR_IRQS #warning No CPU/platform type selected, your kernel will not work! @@ -324,6 +325,10 @@ void __init setup_arch(char **cmdline_p) panic("No configuration setup"); } +#ifdef CONFIG_NATFEAT + nf_init(); +#endif + paging_init(); #ifndef CONFIG_SUN3 diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index d12c3b0d9e4..a0afc239304 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -42,6 +42,7 @@ #include <linux/personality.h> #include <linux/tty.h> #include <linux/binfmts.h> +#include <linux/module.h> #include <asm/setup.h> #include <asm/uaccess.h> @@ -51,7 +52,7 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -const int frame_extra_sizes[16] = { +static const int frame_extra_sizes[16] = { [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ [2] = sizeof(((struct frame *)0)->un.fmt2), [3] = sizeof(((struct frame *)0)->un.fmt3), @@ -69,6 +70,27 @@ const int frame_extra_sizes[16] = { [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */ }; +int handle_kernel_fault(struct pt_regs *regs) +{ + const struct exception_table_entry *fixup; + struct pt_regs *tregs; + + /* Are we prepared to handle this kernel fault? */ + fixup = search_exception_tables(regs->pc); + if (!fixup) + return 0; + + /* Create a new four word stack frame, discarding the old one. */ + regs->stkadj = frame_extra_sizes[regs->format]; + tregs = (struct pt_regs *)((long)regs + regs->stkadj); + tregs->vector = regs->vector; + tregs->format = 0; + tregs->pc = fixup->fixup; + tregs->sr = regs->sr; + + return 1; +} + /* * Atomically swap in the new signal mask, and wait for a signal. */ diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index ada4f4cca81..4022bbc2887 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -48,10 +48,7 @@ asmlinkage void nmihandler(void); asmlinkage void fpu_emu(void); #endif -e_vector vectors[256] = { - [VEC_BUSERR] = buserr, - [VEC_SYS] = system_call, -}; +e_vector vectors[256]; /* nmi handler for the Amiga */ asm(".text\n" @@ -61,10 +58,11 @@ asm(".text\n" /* * this must be called very early as the kernel might * use some instruction that are emulated on the 060 + * and so we're prepared for early probe attempts (e.g. nf_init). */ void __init base_trap_init(void) { - if(MACH_IS_SUN3X) { + if (MACH_IS_SUN3X) { extern e_vector *sun3x_prom_vbr; __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr)); @@ -79,6 +77,10 @@ void __init base_trap_init(void) vectors[VEC_UNIMPII] = unimp_vec; } + + vectors[VEC_BUSERR] = buserr; + vectors[VEC_ILLEGAL] = trap; + vectors[VEC_SYS] = system_call; } void __init trap_init (void) @@ -1055,9 +1057,11 @@ asmlinkage void trap_c(struct frame *fp) siginfo_t info; if (fp->ptregs.sr & PS_S) { - if ((fp->ptregs.vector >> 2) == VEC_TRACE) { - /* traced a trapping instruction */ - } else + if (fp->ptregs.vector == VEC_TRACE << 2) { + /* traced a trapping instruction on a 68020/30, + * real exception will be executed afterwards. + */ + } else if (!handle_kernel_fault(&fp->ptregs)) bad_super_trap(fp); return; } |