X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fum%2Fkernel%2Ftt%2Ftrap_user.c;h=b5d9d64d91e403b82b8d7a6fe525091122b6d9a7;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=67fdef69d54eedb7131b3171a11075bf4990ac13;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c index 67fdef69d..b5d9d64d9 100644 --- a/arch/um/kernel/tt/trap_user.c +++ b/arch/um/kernel/tt/trap_user.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -7,20 +7,19 @@ #include #include #include "sysdep/ptrace.h" -#include "signal_user.h" +#include "sysdep/sigcontext.h" #include "user_util.h" #include "kern_util.h" #include "task.h" #include "tt.h" +#include "os.h" void sig_handler_common_tt(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; struct tt_regs save_regs, *r; - struct signal_info *info; - int save_errno = errno, is_user; - - unprotect_kernel_mem(); + int save_errno = errno, is_user = 0; + void (*handler)(int, union uml_pt_regs *); /* 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, @@ -30,16 +29,26 @@ void sig_handler_common_tt(int sig, void *sc_ptr) change_sig(SIGSEGV, 1); r = &TASK_REGS(get_current())->tt; + if ( sig == SIGFPE || sig == SIGSEGV || + sig == SIGBUS || sig == SIGILL || + sig == SIGTRAP ) { + GET_FAULTINFO_FROM_SC(r->faultinfo, sc); + } save_regs = *r; - is_user = user_context(SC_SP(sc)); + if (sc) + is_user = user_context(SC_SP(sc)); r->sc = sc; if(sig != SIGUSR2) r->syscall = -1; - info = &sig_info[sig]; - if(!info->is_irq) unblock_signals(); + handler = sig_info[sig]; + + /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */ + if (sig != SIGIO && sig != SIGWINCH && + sig != SIGVTALRM && sig != SIGALRM) + unblock_signals(); - (*info->handler)(sig, (union uml_pt_regs *) r); + handler(sig, (union uml_pt_regs *) r); if(is_user){ interrupt_end(); @@ -48,7 +57,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr) } *r = save_regs; errno = save_errno; - if(is_user) protect_kernel_mem(); } /*