aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/signal.c
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2006-09-26 02:33:04 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 11:49:07 -0400
commit4b84c69b5f6c08a540e3683f1360a6cdef2806c7 (patch)
tree708f1e4cbc2771886aaeb8eadb3ae4d458bc8133 /arch/um/os-Linux/signal.c
parent19bdf0409f25a85a45874a5a8da6f3e4edcf4a49 (diff)
[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 <jdike@addtoit.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/os-Linux/signal.c')
-rw-r--r--arch/um/os-Linux/signal.c31
1 files changed, 13 insertions, 18 deletions
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 60e4faedf254..55b62e2b8f41 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -15,7 +15,6 @@
15#include "user.h" 15#include "user.h"
16#include "signal_kern.h" 16#include "signal_kern.h"
17#include "sysdep/sigcontext.h" 17#include "sysdep/sigcontext.h"
18#include "sysdep/signal.h"
19#include "sigcontext.h" 18#include "sigcontext.h"
20#include "mode.h" 19#include "mode.h"
21#include "os.h" 20#include "os.h"
@@ -38,18 +37,10 @@
38static int signals_enabled = 1; 37static int signals_enabled = 1;
39static int pending = 0; 38static int pending = 0;
40 39
41void sig_handler(ARCH_SIGHDLR_PARAM) 40void sig_handler(int sig, struct sigcontext *sc)
42{ 41{
43 struct sigcontext *sc;
44 int enabled; 42 int enabled;
45 43
46 /* Must be the first thing that this handler does - x86_64 stores
47 * the sigcontext in %rdx, and we need to save it before it has a
48 * chance to get trashed.
49 */
50
51 ARCH_GET_SIGCONTEXT(sc, sig);
52
53 enabled = signals_enabled; 44 enabled = signals_enabled;
54 if(!enabled && (sig == SIGIO)){ 45 if(!enabled && (sig == SIGIO)){
55 pending |= SIGIO_MASK; 46 pending |= SIGIO_MASK;
@@ -84,13 +75,10 @@ static void real_alarm_handler(int sig, struct sigcontext *sc)
84 75
85} 76}
86 77
87void alarm_handler(ARCH_SIGHDLR_PARAM) 78void alarm_handler(int sig, struct sigcontext *sc)
88{ 79{
89 struct sigcontext *sc;
90 int enabled; 80 int enabled;
91 81
92 ARCH_GET_SIGCONTEXT(sc, sig);
93
94 enabled = signals_enabled; 82 enabled = signals_enabled;
95 if(!signals_enabled){ 83 if(!signals_enabled){
96 if(sig == SIGVTALRM) 84 if(sig == SIGVTALRM)
@@ -126,6 +114,10 @@ void remove_sigstack(void)
126 panic("disabling signal stack failed, errno = %d\n", errno); 114 panic("disabling signal stack failed, errno = %d\n", errno);
127} 115}
128 116
117void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
118
119extern void hard_handler(int sig);
120
129void set_handler(int sig, void (*handler)(int), int flags, ...) 121void set_handler(int sig, void (*handler)(int), int flags, ...)
130{ 122{
131 struct sigaction action; 123 struct sigaction action;
@@ -133,13 +125,16 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
133 sigset_t sig_mask; 125 sigset_t sig_mask;
134 int mask; 126 int mask;
135 127
136 va_start(ap, flags); 128 handlers[sig] = (void (*)(int, struct sigcontext *)) handler;
137 action.sa_handler = handler; 129 action.sa_handler = hard_handler;
130
138 sigemptyset(&action.sa_mask); 131 sigemptyset(&action.sa_mask);
139 while((mask = va_arg(ap, int)) != -1){ 132
133 va_start(ap, flags);
134 while((mask = va_arg(ap, int)) != -1)
140 sigaddset(&action.sa_mask, mask); 135 sigaddset(&action.sa_mask, mask);
141 }
142 va_end(ap); 136 va_end(ap);
137
143 action.sa_flags = flags; 138 action.sa_flags = flags;
144 action.sa_restorer = NULL; 139 action.sa_restorer = NULL;
145 if(sigaction(sig, &action, NULL) < 0) 140 if(sigaction(sig, &action, NULL) < 0)