diff options
author | Jeff Dike <jdike@addtoit.com> | 2006-09-26 02:33:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:49:07 -0400 |
commit | 4b84c69b5f6c08a540e3683f1360a6cdef2806c7 (patch) | |
tree | 708f1e4cbc2771886aaeb8eadb3ae4d458bc8133 /arch/um/os-Linux/signal.c | |
parent | 19bdf0409f25a85a45874a5a8da6f3e4edcf4a49 (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.c | 31 |
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 @@ | |||
38 | static int signals_enabled = 1; | 37 | static int signals_enabled = 1; |
39 | static int pending = 0; | 38 | static int pending = 0; |
40 | 39 | ||
41 | void sig_handler(ARCH_SIGHDLR_PARAM) | 40 | void 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 | ||
87 | void alarm_handler(ARCH_SIGHDLR_PARAM) | 78 | void 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 | ||
117 | void (*handlers[_NSIG])(int sig, struct sigcontext *sc); | ||
118 | |||
119 | extern void hard_handler(int sig); | ||
120 | |||
129 | void set_handler(int sig, void (*handler)(int), int flags, ...) | 121 | void 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) |