From zippel@linux-m68k.org Mon May 26 17:03:35 2008 Date: Mon, 26 May 2008 17:03:19 +0200 (CEST) From: Roman Zippel To: Andreas Schwab Cc: Geert Uytterhoeven , Linux/m68k Subject: Re: nf_get_id() and real hardware Hi, On Sun, 25 May 2008, Andreas Schwab wrote: > Thanks for testing, I have checked it into CVS. I committed the cleanup patch below on top of it. bye, Roman Add helper function handle_kernel_fault() in signal.c, so frame_extra_sizes can become static and to reduce code duplication. Use base_trap_init() to initialize vectors, so basic initialization is all in one place. Remove the VEC_TRACE check from trap_c, I can only guess it's left from an old kgdb patch, as right now it does nothing. Signed-off-by: Roman Zippel --- arch/m68k/kernel/signal.c | 24 +++++++++++++++++++++++- arch/m68k/kernel/traps.c | 38 ++++++++------------------------------ arch/m68k/mm/fault.c | 16 +--------------- include/asm-m68k/processor.h | 2 ++ 4 files changed, 34 insertions(+), 46 deletions(-) --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -53,7 +54,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); -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), @@ -71,6 +72,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. */ --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -48,11 +48,7 @@ asmlinkage void nmihandler(void); asmlinkage void fpu_emu(void); #endif -e_vector vectors[256] = { - [VEC_BUSERR] = buserr, - [VEC_ILLEGAL] = trap, /* needed for nf_init */ - [VEC_SYS] = system_call, -}; +e_vector vectors[256]; /* nmi handler for the Amiga */ asm(".text\n" @@ -62,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)); @@ -80,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) @@ -1019,28 +1020,8 @@ void dump_stack(void) EXPORT_SYMBOL(dump_stack); -extern const int frame_extra_sizes[]; /* in m68k/kernel/signal.c */ - void bad_super_trap (struct frame *fp) { - const struct exception_table_entry *fixup; - - /* Are we prepared to handle this kernel fault? */ - fixup = search_exception_tables(fp->ptregs.pc); - if (fixup) { - struct pt_regs *regs, *tregs; - /* Create a new four word stack frame, discarding the old - one. */ - regs = &fp->ptregs; - regs->stkadj = frame_extra_sizes[regs->format]; - tregs = (struct pt_regs *)((ulong)regs + regs->stkadj); - tregs->vector = regs->vector; - tregs->format = 0; - tregs->pc = fixup->fixup; - tregs->sr = regs->sr; - return; - } - console_verbose(); if (fp->ptregs.vector < 4 * ARRAY_SIZE(vec_names)) printk ("*** %s *** FORMAT=%X\n", @@ -1079,10 +1060,7 @@ 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 */ - current->ptrace |= PT_DTRACE; - } else + if (!handle_kernel_fault(&fp->ptregs)) bad_super_trap(fp); return; } --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c @@ -18,7 +18,6 @@ #include extern void die_if_kernel(char *, struct pt_regs *, long); -extern const int frame_extra_sizes[]; /* in m68k/kernel/signal.c */ int send_fault_sig(struct pt_regs *regs) { @@ -35,21 +34,8 @@ int send_fault_sig(struct pt_regs *regs) force_sig_info(siginfo.si_signo, &siginfo, current); } else { - const struct exception_table_entry *fixup; - - /* Are we prepared to handle this kernel fault? */ - if ((fixup = search_exception_tables(regs->pc))) { - struct pt_regs *tregs; - /* Create a new four word stack frame, discarding the old - one. */ - regs->stkadj = frame_extra_sizes[regs->format]; - tregs = (struct pt_regs *)((ulong)regs + regs->stkadj); - tregs->vector = regs->vector; - tregs->format = 0; - tregs->pc = fixup->fixup; - tregs->sr = regs->sr; + if (handle_kernel_fault(regs)) return -1; - } //if (siginfo.si_signo == SIGBUS) // force_sig_info(siginfo.si_signo, --- a/include/asm-m68k/processor.h +++ b/include/asm-m68k/processor.h @@ -127,4 +127,6 @@ unsigned long get_wchan(struct task_stru #define cpu_relax() barrier() +extern int handle_kernel_fault(struct pt_regs *regs); + #endif