diff options
Diffstat (limited to 'arch/um/os-Linux/skas/trap.c')
-rw-r--r-- | arch/um/os-Linux/skas/trap.c | 49 |
1 files changed, 21 insertions, 28 deletions
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c index 9ad5fbec459..3b600c2e63b 100644 --- a/arch/um/os-Linux/skas/trap.c +++ b/arch/um/os-Linux/skas/trap.c @@ -5,8 +5,8 @@ #include <signal.h> #include <errno.h> -#include "user_util.h" #include "kern_util.h" +#include "as-layout.h" #include "task.h" #include "sigcontext.h" #include "skas.h" @@ -15,29 +15,39 @@ #include "sysdep/ptrace_user.h" #include "os.h" +static union uml_pt_regs ksig_regs[UM_NR_CPUS]; + void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; - struct skas_regs *r; + union uml_pt_regs *r; void (*handler)(int, union uml_pt_regs *); - int save_errno = errno; - int save_user; + int save_user, save_errno = errno; /* This is done because to allow SIGSEGV to be delivered inside a SEGV * handler. This can happen in copy_user, and if SEGV is disabled, * the process will die. * XXX Figure out why this is better than SA_NODEFER */ - if(sig == SIGSEGV) + if(sig == SIGSEGV) { change_sig(SIGSEGV, 1); + /* For segfaults, we want the data from the + * sigcontext. In this case, we don't want to mangle + * the process registers, so use a static set of + * registers. For other signals, the process + * registers are OK. + */ + r = &ksig_regs[cpu()]; + copy_sc(r, sc_ptr); + } + else r = TASK_REGS(get_current()); - r = &TASK_REGS(get_current())->skas; - save_user = r->is_user; - r->is_user = 0; + save_user = r->skas.is_user; + r->skas.is_user = 0; if ( sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || sig == SIGTRAP ) { - GET_FAULTINFO_FROM_SC(r->faultinfo, sc); + GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc); } change_sig(SIGUSR1, 1); @@ -49,25 +59,8 @@ void sig_handler_common_skas(int sig, void *sc_ptr) sig != SIGVTALRM && sig != SIGALRM) unblock_signals(); - handler(sig, (union uml_pt_regs *) r); + handler(sig, r); errno = save_errno; - r->is_user = save_user; -} - -extern int ptrace_faultinfo; - -void user_signal(int sig, union uml_pt_regs *regs, int pid) -{ - void (*handler)(int, union uml_pt_regs *); - int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || - (sig == SIGILL) || (sig == SIGTRAP)); - - if (segv) - get_skas_faultinfo(pid, ®s->skas.faultinfo); - - handler = sig_info[sig]; - handler(sig, (union uml_pt_regs *) regs); - - unblock_signals(); + r->skas.is_user = save_user; } |