uml: separate timer initialization
[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 "os.h"
13 #include "sysdep/barrier.h"
14 #include "sysdep/sigcontext.h"
15 #include "user.h"
16
17 /*
18  * These are the asynchronous signals.  SIGVTALRM and SIGARLM are handled
19  * together under SIGVTALRM_BIT.  SIGPROF is excluded because we want to
20  * be able to profile all of UML, not just the non-critical sections.  If
21  * profiling is not thread-safe, then that is not my problem.  We can disable
22  * profiling when SMP is enabled in that case.
23  */
24 #define SIGIO_BIT 0
25 #define SIGIO_MASK (1 << SIGIO_BIT)
26
27 #define SIGVTALRM_BIT 1
28 #define SIGVTALRM_MASK (1 << SIGVTALRM_BIT)
29
30 #define SIGALRM_BIT 2
31 #define SIGALRM_MASK (1 << SIGALRM_BIT)
32
33 /*
34  * These are used by both the signal handlers and
35  * block/unblock_signals.  I don't want modifications cached in a
36  * register - they must go straight to memory.
37  */
38 static volatile int signals_enabled = 1;
39 static volatile int pending = 0;
40
41 void sig_handler(int sig, struct sigcontext *sc)
42 {
43         int enabled;
44
45         enabled = signals_enabled;
46         if (!enabled && (sig == SIGIO)) {
47                 pending |= SIGIO_MASK;
48                 return;
49         }
50
51         block_signals();
52
53         sig_handler_common_skas(sig, sc);
54
55         set_signals(enabled);
56 }
57
58 static void real_alarm_handler(int sig, struct sigcontext *sc)
59 {
60         struct uml_pt_regs regs;
61
62         if (sc != NULL)
63                 copy_sc(&regs, sc);
64         regs.is_user = 0;
65         unblock_signals();
66         timer_handler(sig, &regs);
67 }
68
69 void alarm_handler(int sig, struct sigcontext *sc)
70 {
71         int enabled;
72
73         enabled = signals_enabled;
74         if (!signals_enabled) {
75                 if (sig == SIGVTALRM)
76                         pending |= SIGVTALRM_MASK;
77                 else pending |= SIGALRM_MASK;
78
79                 return;
80         }
81
82         block_signals();
83
84         real_alarm_handler(sig, sc);
85         set_signals(enabled);
86 }
87
88 void timer_init(void)
89 {
90         set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
91                     SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
92                     SIGALRM, -1);
93         set_handler(SIGALRM, (__sighandler_t) alarm_handler,
94                     SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
95                     SIGALRM, -1);
96 }
97
98 void set_sigstack(void *sig_stack, int size)
99 {
100         stack_t stack = ((stack_t) { .ss_flags  = 0,
101                                      .ss_sp     = (__ptr_t) sig_stack,
102                                      .ss_size   = size - sizeof(void *) });
103
104         if (sigaltstack(&stack, NULL) != 0)
105                 panic("enabling signal stack failed, errno = %d\n", errno);
106 }
107
108 void remove_sigstack(void)
109 {
110         stack_t stack = ((stack_t) { .ss_flags  = SS_DISABLE,
111                                      .ss_sp     = NULL,
112                                      .ss_size   = 0 });
113
114         if (sigaltstack(&stack, NULL) != 0)
115                 panic("disabling signal stack failed, errno = %d\n", errno);
116 }
117
118 void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
119
120 void handle_signal(int sig, struct sigcontext *sc)
121 {
122         unsigned long pending = 1UL << sig;
123         int timer = switch_timers(0);
124
125         do {
126                 int nested, bail;
127
128                 /*
129                  * pending comes back with one bit set for each
130                  * interrupt that arrived while setting up the stack,
131                  * plus a bit for this interrupt, plus the zero bit is
132                  * set if this is a nested interrupt.
133                  * If bail is true, then we interrupted another
134                  * handler setting up the stack.  In this case, we
135                  * have to return, and the upper handler will deal
136                  * with this interrupt.
137                  */
138                 bail = to_irq_stack(&pending);
139                 if (bail)
140                         return;
141
142                 nested = pending & 1;
143                 pending &= ~1;
144
145                 while ((sig = ffs(pending)) != 0){
146                         sig--;
147                         pending &= ~(1 << sig);
148                         (*handlers[sig])(sig, sc);
149                 }
150
151                 /*
152                  * Again, pending comes back with a mask of signals
153                  * that arrived while tearing down the stack.  If this
154                  * is non-zero, we just go back, set up the stack
155                  * again, and handle the new interrupts.
156                  */
157                 if (!nested)
158                         pending = from_irq_stack(nested);
159         } while (pending);
160
161         switch_timers(timer);
162 }
163
164 extern void hard_handler(int sig);
165
166 void set_handler(int sig, void (*handler)(int), int flags, ...)
167 {
168         struct sigaction action;
169         va_list ap;
170         sigset_t sig_mask;
171         int mask;
172
173         handlers[sig] = (void (*)(int, struct sigcontext *)) handler;
174         action.sa_handler = hard_handler;
175
176         sigemptyset(&action.sa_mask);
177
178         va_start(ap, flags);
179         while ((mask = va_arg(ap, int)) != -1)
180                 sigaddset(&action.sa_mask, mask);
181         va_end(ap);
182
183         action.sa_flags = flags;
184         action.sa_restorer = NULL;
185         if (sigaction(sig, &action, NULL) < 0)
186                 panic("sigaction failed - errno = %d\n", errno);
187
188         sigemptyset(&sig_mask);
189         sigaddset(&sig_mask, sig);
190         if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
191                 panic("sigprocmask failed - errno = %d\n", errno);
192 }
193
194 int change_sig(int signal, int on)
195 {
196         sigset_t sigset, old;
197
198         sigemptyset(&sigset);
199         sigaddset(&sigset, signal);
200         sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
201         return !sigismember(&old, signal);
202 }
203
204 void block_signals(void)
205 {
206         signals_enabled = 0;
207         /*
208          * This must return with signals disabled, so this barrier
209          * ensures that writes are flushed out before the return.
210          * This might matter if gcc figures out how to inline this and
211          * decides to shuffle this code into the caller.
212          */
213         mb();
214 }
215
216 void unblock_signals(void)
217 {
218         int save_pending;
219
220         if (signals_enabled == 1)
221                 return;
222
223         /*
224          * We loop because the IRQ handler returns with interrupts off.  So,
225          * interrupts may have arrived and we need to re-enable them and
226          * recheck pending.
227          */
228         while(1) {
229                 /*
230                  * Save and reset save_pending after enabling signals.  This
231                  * way, pending won't be changed while we're reading it.
232                  */
233                 signals_enabled = 1;
234
235                 /*
236                  * Setting signals_enabled and reading pending must
237                  * happen in this order.
238                  */
239                 mb();
240
241                 save_pending = pending;
242                 if (save_pending == 0) {
243                         /*
244                          * This must return with signals enabled, so
245                          * this barrier ensures that writes are
246                          * flushed out before the return.  This might
247                          * matter if gcc figures out how to inline
248                          * this (unlikely, given its size) and decides
249                          * to shuffle this code into the caller.
250                          */
251                         mb();
252                         return;
253                 }
254
255                 pending = 0;
256
257                 /*
258                  * We have pending interrupts, so disable signals, as the
259                  * handlers expect them off when they are called.  They will
260                  * be enabled again above.
261                  */
262
263                 signals_enabled = 0;
264
265                 /*
266                  * Deal with SIGIO first because the alarm handler might
267                  * schedule, leaving the pending SIGIO stranded until we come
268                  * back here.
269                  */
270                 if (save_pending & SIGIO_MASK)
271                         sig_handler_common_skas(SIGIO, NULL);
272
273                 if (save_pending & SIGALRM_MASK)
274                         real_alarm_handler(SIGALRM, NULL);
275
276                 if (save_pending & SIGVTALRM_MASK)
277                         real_alarm_handler(SIGVTALRM, NULL);
278         }
279 }
280
281 int get_signals(void)
282 {
283         return signals_enabled;
284 }
285
286 int set_signals(int enable)
287 {
288         int ret;
289         if (signals_enabled == enable)
290                 return enable;
291
292         ret = signals_enabled;
293         if (enable)
294                 unblock_signals();
295         else block_signals();
296
297         return ret;
298 }