uml: move sig_handler_common_skas
[safe/jmp/linux-2.6] / arch / um / os-Linux / signal.c
1 /*
2  * Copyright (C) 2004 PathScale, Inc
3  * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4  * Licensed under the GPL
5  */
6
7 #include <stdlib.h>
8 #include <stdarg.h>
9 #include <errno.h>
10 #include <signal.h>
11 #include <strings.h>
12 #include "as-layout.h"
13 #include "kern_constants.h"
14 #include "kern_util.h"
15 #include "os.h"
16 #include "sysdep/barrier.h"
17 #include "sysdep/sigcontext.h"
18 #include "task.h"
19 #include "user.h"
20
21 void (*sig_info[NSIG])(int, struct uml_pt_regs *) = {
22         [SIGTRAP]       = relay_signal,
23         [SIGFPE]        = relay_signal,
24         [SIGILL]        = relay_signal,
25         [SIGWINCH]      = winch,
26         [SIGBUS]        = bus_handler,
27         [SIGSEGV]       = segv_handler,
28         [SIGIO]         = sigio_handler,
29         [SIGVTALRM]     = timer_handler };
30
31 static struct uml_pt_regs ksig_regs[UM_NR_CPUS];
32
33 void sig_handler_common_skas(int sig, void *sc_ptr)
34 {
35         struct sigcontext *sc = sc_ptr;
36         struct uml_pt_regs *r;
37         void (*handler)(int, struct uml_pt_regs *);
38         int save_user, save_errno = errno;
39
40         /*
41          * This is done because to allow SIGSEGV to be delivered inside a SEGV
42          * handler.  This can happen in copy_user, and if SEGV is disabled,
43          * the process will die.
44          * XXX Figure out why this is better than SA_NODEFER
45          */
46         if (sig == SIGSEGV) {
47                 change_sig(SIGSEGV, 1);
48                 /*
49                  * For segfaults, we want the data from the
50                  * sigcontext.  In this case, we don't want to mangle
51                  * the process registers, so use a static set of
52                  * registers.  For other signals, the process
53                  * registers are OK.
54                  */
55                 r = &ksig_regs[cpu()];
56                 copy_sc(r, sc_ptr);
57         } else
58                 r = TASK_REGS(get_current());
59
60         save_user = r->is_user;
61         r->is_user = 0;
62         if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
63             (sig == SIGILL) || (sig == SIGTRAP))
64                 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
65
66         change_sig(SIGUSR1, 1);
67
68         handler = sig_info[sig];
69
70         /* unblock SIGVTALRM, SIGIO if sig isn't IRQ signal */
71         if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM))
72                 unblock_signals();
73
74         handler(sig, r);
75
76         errno = save_errno;
77         r->is_user = save_user;
78 }
79
80 /* Copied from linux/compiler-gcc.h since we can't include it directly */
81 #define barrier() __asm__ __volatile__("": : :"memory")
82
83 /*
84  * These are the asynchronous signals.  SIGPROF is excluded because we want to
85  * be able to profile all of UML, not just the non-critical sections.  If
86  * profiling is not thread-safe, then that is not my problem.  We can disable
87  * profiling when SMP is enabled in that case.
88  */
89 #define SIGIO_BIT 0
90 #define SIGIO_MASK (1 << SIGIO_BIT)
91
92 #define SIGVTALRM_BIT 1
93 #define SIGVTALRM_MASK (1 << SIGVTALRM_BIT)
94
95 static int signals_enabled;
96 static unsigned int pending;
97
98 void sig_handler(int sig, struct sigcontext *sc)
99 {
100         int enabled;
101
102         enabled = signals_enabled;
103         if (!enabled && (sig == SIGIO)) {
104                 pending |= SIGIO_MASK;
105                 return;
106         }
107
108         block_signals();
109
110         sig_handler_common_skas(sig, sc);
111
112         set_signals(enabled);
113 }
114
115 static void real_alarm_handler(struct sigcontext *sc)
116 {
117         struct uml_pt_regs regs;
118
119         if (sc != NULL)
120                 copy_sc(&regs, sc);
121         regs.is_user = 0;
122         unblock_signals();
123         timer_handler(SIGVTALRM, &regs);
124 }
125
126 void alarm_handler(int sig, struct sigcontext *sc)
127 {
128         int enabled;
129
130         enabled = signals_enabled;
131         if (!signals_enabled) {
132                 pending |= SIGVTALRM_MASK;
133                 return;
134         }
135
136         block_signals();
137
138         real_alarm_handler(sc);
139         set_signals(enabled);
140 }
141
142 void timer_init(void)
143 {
144         set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
145                     SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, -1);
146 }
147
148 void set_sigstack(void *sig_stack, int size)
149 {
150         stack_t stack = ((stack_t) { .ss_flags  = 0,
151                                      .ss_sp     = (__ptr_t) sig_stack,
152                                      .ss_size   = size - sizeof(void *) });
153
154         if (sigaltstack(&stack, NULL) != 0)
155                 panic("enabling signal stack failed, errno = %d\n", errno);
156 }
157
158 void remove_sigstack(void)
159 {
160         stack_t stack = ((stack_t) { .ss_flags  = SS_DISABLE,
161                                      .ss_sp     = NULL,
162                                      .ss_size   = 0 });
163
164         if (sigaltstack(&stack, NULL) != 0)
165                 panic("disabling signal stack failed, errno = %d\n", errno);
166 }
167
168 void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
169
170 void handle_signal(int sig, struct sigcontext *sc)
171 {
172         unsigned long pending = 1UL << sig;
173
174         do {
175                 int nested, bail;
176
177                 /*
178                  * pending comes back with one bit set for each
179                  * interrupt that arrived while setting up the stack,
180                  * plus a bit for this interrupt, plus the zero bit is
181                  * set if this is a nested interrupt.
182                  * If bail is true, then we interrupted another
183                  * handler setting up the stack.  In this case, we
184                  * have to return, and the upper handler will deal
185                  * with this interrupt.
186                  */
187                 bail = to_irq_stack(&pending);
188                 if (bail)
189                         return;
190
191                 nested = pending & 1;
192                 pending &= ~1;
193
194                 while ((sig = ffs(pending)) != 0){
195                         sig--;
196                         pending &= ~(1 << sig);
197                         (*handlers[sig])(sig, sc);
198                 }
199
200                 /*
201                  * Again, pending comes back with a mask of signals
202                  * that arrived while tearing down the stack.  If this
203                  * is non-zero, we just go back, set up the stack
204                  * again, and handle the new interrupts.
205                  */
206                 if (!nested)
207                         pending = from_irq_stack(nested);
208         } while (pending);
209 }
210
211 extern void hard_handler(int sig);
212
213 void set_handler(int sig, void (*handler)(int), int flags, ...)
214 {
215         struct sigaction action;
216         va_list ap;
217         sigset_t sig_mask;
218         int mask;
219
220         handlers[sig] = (void (*)(int, struct sigcontext *)) handler;
221         action.sa_handler = hard_handler;
222
223         sigemptyset(&action.sa_mask);
224
225         va_start(ap, flags);
226         while ((mask = va_arg(ap, int)) != -1)
227                 sigaddset(&action.sa_mask, mask);
228         va_end(ap);
229
230         action.sa_flags = flags;
231         action.sa_restorer = NULL;
232         if (sigaction(sig, &action, NULL) < 0)
233                 panic("sigaction failed - errno = %d\n", errno);
234
235         sigemptyset(&sig_mask);
236         sigaddset(&sig_mask, sig);
237         if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
238                 panic("sigprocmask failed - errno = %d\n", errno);
239 }
240
241 int change_sig(int signal, int on)
242 {
243         sigset_t sigset, old;
244
245         sigemptyset(&sigset);
246         sigaddset(&sigset, signal);
247         if (sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old) < 0)
248                 return -errno;
249         return !sigismember(&old, signal);
250 }
251
252 void block_signals(void)
253 {
254         signals_enabled = 0;
255         /*
256          * This must return with signals disabled, so this barrier
257          * ensures that writes are flushed out before the return.
258          * This might matter if gcc figures out how to inline this and
259          * decides to shuffle this code into the caller.
260          */
261         barrier();
262 }
263
264 void unblock_signals(void)
265 {
266         int save_pending;
267
268         if (signals_enabled == 1)
269                 return;
270
271         /*
272          * We loop because the IRQ handler returns with interrupts off.  So,
273          * interrupts may have arrived and we need to re-enable them and
274          * recheck pending.
275          */
276         while(1) {
277                 /*
278                  * Save and reset save_pending after enabling signals.  This
279                  * way, pending won't be changed while we're reading it.
280                  */
281                 signals_enabled = 1;
282
283                 /*
284                  * Setting signals_enabled and reading pending must
285                  * happen in this order.
286                  */
287                 barrier();
288
289                 save_pending = pending;
290                 if (save_pending == 0)
291                         return;
292
293                 pending = 0;
294
295                 /*
296                  * We have pending interrupts, so disable signals, as the
297                  * handlers expect them off when they are called.  They will
298                  * be enabled again above.
299                  */
300
301                 signals_enabled = 0;
302
303                 /*
304                  * Deal with SIGIO first because the alarm handler might
305                  * schedule, leaving the pending SIGIO stranded until we come
306                  * back here.
307                  */
308                 if (save_pending & SIGIO_MASK)
309                         sig_handler_common_skas(SIGIO, NULL);
310
311                 if (save_pending & SIGVTALRM_MASK)
312                         real_alarm_handler(NULL);
313         }
314 }
315
316 int get_signals(void)
317 {
318         return signals_enabled;
319 }
320
321 int set_signals(int enable)
322 {
323         int ret;
324         if (signals_enabled == enable)
325                 return enable;
326
327         ret = signals_enabled;
328         if (enable)
329                 unblock_signals();
330         else block_signals();
331
332         return ret;
333 }