m68k: Add helper function handle_kernel_fault()

Add helper function handle_kernel_fault() in signal.c, so frame_extra_sizes
can become static, and to avoid future code duplication.

Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
This commit is contained in:
Roman Zippel 2008-11-18 21:25:17 +01:00 committed by Geert Uytterhoeven
parent 521cb40b0c
commit dcdf3a2935
3 changed files with 26 additions and 16 deletions

View File

@ -113,6 +113,8 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc,
wrusp(usp); wrusp(usp);
} }
extern int handle_kernel_fault(struct pt_regs *regs);
#else #else
/* /*

View File

@ -42,6 +42,7 @@
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/module.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
@ -51,7 +52,7 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #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), */ [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */
[2] = sizeof(((struct frame *)0)->un.fmt2), [2] = sizeof(((struct frame *)0)->un.fmt2),
[3] = sizeof(((struct frame *)0)->un.fmt3), [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), */ [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. * Atomically swap in the new signal mask, and wait for a signal.
*/ */

View File

@ -18,7 +18,6 @@
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
extern void die_if_kernel(char *, struct pt_regs *, long); 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) 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, force_sig_info(siginfo.si_signo,
&siginfo, current); &siginfo, current);
} else { } else {
const struct exception_table_entry *fixup; if (handle_kernel_fault(regs))
/* 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;
return -1; return -1;
}
//if (siginfo.si_signo == SIGBUS) //if (siginfo.si_signo == SIGBUS)
// force_sig_info(siginfo.si_signo, // force_sig_info(siginfo.si_signo,