From 4b84c69b5f6c08a540e3683f1360a6cdef2806c7 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Mon, 25 Sep 2006 23:33:04 -0700 Subject: [PATCH] uml: Move signal handlers to arch code Have most signals go through an arch-provided handler which recovers the sigcontext and then calls a generic handler. This replaces the ARCH_GET_SIGCONTEXT macro, which was somewhat fragile. On x86_64, recovering %rdx (which holds the sigcontext pointer) must be the first thing that happens. sig_handler duly invokes that first, but there is no guarantee that I can see that instructions won't be reordered such that %rdx is used before that. Having the arch provide the handler seems much more robust. Some signals in some parts of UML require their own handlers - these places don't call set_handler any more. They call sigaction or signal themselves. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/signal.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) (limited to 'arch/um/os-Linux/signal.c') diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 60e4faedf25..55b62e2b8f4 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -15,7 +15,6 @@ #include "user.h" #include "signal_kern.h" #include "sysdep/sigcontext.h" -#include "sysdep/signal.h" #include "sigcontext.h" #include "mode.h" #include "os.h" @@ -38,18 +37,10 @@ static int signals_enabled = 1; static int pending = 0; -void sig_handler(ARCH_SIGHDLR_PARAM) +void sig_handler(int sig, struct sigcontext *sc) { - struct sigcontext *sc; int enabled; - /* Must be the first thing that this handler does - x86_64 stores - * the sigcontext in %rdx, and we need to save it before it has a - * chance to get trashed. - */ - - ARCH_GET_SIGCONTEXT(sc, sig); - enabled = signals_enabled; if(!enabled && (sig == SIGIO)){ pending |= SIGIO_MASK; @@ -84,13 +75,10 @@ static void real_alarm_handler(int sig, struct sigcontext *sc) } -void alarm_handler(ARCH_SIGHDLR_PARAM) +void alarm_handler(int sig, struct sigcontext *sc) { - struct sigcontext *sc; int enabled; - ARCH_GET_SIGCONTEXT(sc, sig); - enabled = signals_enabled; if(!signals_enabled){ if(sig == SIGVTALRM) @@ -126,6 +114,10 @@ void remove_sigstack(void) panic("disabling signal stack failed, errno = %d\n", errno); } +void (*handlers[_NSIG])(int sig, struct sigcontext *sc); + +extern void hard_handler(int sig); + void set_handler(int sig, void (*handler)(int), int flags, ...) { struct sigaction action; @@ -133,13 +125,16 @@ void set_handler(int sig, void (*handler)(int), int flags, ...) sigset_t sig_mask; int mask; - va_start(ap, flags); - action.sa_handler = handler; + handlers[sig] = (void (*)(int, struct sigcontext *)) handler; + action.sa_handler = hard_handler; + sigemptyset(&action.sa_mask); - while((mask = va_arg(ap, int)) != -1){ + + va_start(ap, flags); + while((mask = va_arg(ap, int)) != -1) sigaddset(&action.sa_mask, mask); - } va_end(ap); + action.sa_flags = flags; action.sa_restorer = NULL; if(sigaction(sig, &action, NULL) < 0) -- cgit v1.2.3