dbe6b421fb060032dc41513bffd340458e4d7521
[akaros.git] / user / parlib / signal.c
1 /* Copyright (c) 2013 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * Kevin Klues <klueska@cs.berkeley.edu>
4  * See LICENSE for details.
5  *
6  * POSIX signal handling glue.  All glibc programs link against parlib, so they
7  * will get this mixed in.  Mostly just registration of signal handlers.
8  *
9  * POSIX signal handling caveats:
10  *      - We don't copy signal handling tables or anything across forks or execs
11  *      - We don't send meaningful info in the siginfos, nor do we pass pid/uids on
12  *      signals coming from a kill.  This is especially pertinent for sigqueue,
13  *      which needs a payload (value) and sending PID
14  *      - We run handlers in vcore context, so any blocking syscall will spin.
15  *      Regular signals have restrictions on their syscalls too, though not this
16  *      great.  We could spawn off a uthread to run the handler, given that we have
17  *      a 2LS (which we don't for SCPs).
18  *      - We don't do anything with signal blocking/masking.  When in a signal
19  *      handler, you won't get interrupted with another signal handler (so long as
20  *      you run it in vcore context!).  With uthreads, you could get interrupted.
21  *      There is also no process wide signal blocking yet (sigprocmask()).  If this
22  *      is desired, we can abort certain signals when we h_p_signal(), 
23  *      - Likewise, we don't do waiting for particular signals yet.  Just about the
24  *      only thing we do is allow the registration of signal handlers. 
25  *      - Check each function for further notes.  */
26
27 // Needed for sigmask functions...
28 #define _GNU_SOURCE
29
30 #include <stdio.h>
31 #include <parlib/parlib.h>
32 #include <parlib/signal.h>
33 #include <parlib/uthread.h>
34 #include <parlib/event.h>
35 #include <parlib/ros_debug.h>
36 #include <errno.h>
37 #include <stdlib.h>
38 #include <parlib/assert.h>
39 #include <ros/procinfo.h>
40 #include <ros/syscall.h>
41 #include <sys/mman.h>
42 #include <parlib/stdio.h>
43
44 /* Forward declare our signal_ops functions. */
45 static int __sigaltstack(__const struct sigaltstack *__restrict __ss,
46                          struct sigaltstack *__restrict __oss);
47 static int __siginterrupt(int __sig, int __interrupt);
48 static int __sigpending(sigset_t *__set);
49 static int __sigprocmask(int __how, __const sigset_t *__restrict __set,
50                          sigset_t *__restrict __oset);
51 static int __sigqueue(__pid_t __pid, int __sig, __const union sigval __val);
52 static int __sigreturn(struct sigcontext *__scp);
53 static int __sigstack(struct sigstack *__ss, struct sigstack *__oss);
54 static int __sigsuspend(__const sigset_t *__set);
55 static int __sigtimedwait(__const sigset_t *__restrict __set,
56                           siginfo_t *__restrict __info,
57                           __const struct timespec *__restrict __timeout);
58 static int __sigwait(__const sigset_t *__restrict __set, int *__restrict __sig);
59 static int __sigwaitinfo(__const sigset_t *__restrict __set,
60                          siginfo_t *__restrict __info);
61 static int __sigself(int signo);
62
63 /* The default definition of signal_ops (similar to sched_ops in uthread.c) */
64 struct signal_ops default_signal_ops = {
65         .sigaltstack = __sigaltstack,
66         .siginterrupt = __siginterrupt,
67         .sigpending = __sigpending,
68         .sigprocmask = __sigprocmask,
69         .sigqueue = __sigqueue,
70         .sigreturn = __sigreturn,
71         .sigstack = __sigstack,
72         .sigsuspend = __sigsuspend,
73         .sigtimedwait = __sigtimedwait,
74         .sigwait = __sigwait,
75         .sigwaitinfo = __sigwaitinfo,
76         .sigself = __sigself
77 };
78
79 /* This is the catch all akaros event->posix signal handler.  All posix signals
80  * are received in a single akaros event type.  They are then dispatched from
81  * this function to their proper posix signal handler */
82 static void handle_event(struct event_msg *ev_msg, unsigned int ev_type,
83                          void *data)
84 {
85         int sig_nr;
86         struct siginfo info = {0};
87         info.si_code = SI_USER;
88         struct user_context fake_uctx;
89
90         assert(ev_msg);
91         sig_nr = ev_msg->ev_arg1;
92         /* We're handling a process-wide signal, but signal handlers will want a
93          * user context.  They operate on the model that some thread got the signal,
94          * but that didn't happen on Akaros.  If we happen to have a current
95          * uthread, we can use that - perhaps that's what the user wants.  If not,
96          * we'll build a fake one representing our current call stack. */
97         if (current_uthread) {
98                 trigger_posix_signal(sig_nr, &info, get_cur_uth_ctx());
99         } else {
100                 init_user_ctx(&fake_uctx, (uintptr_t)handle_event, get_stack_pointer());
101                 trigger_posix_signal(sig_nr, &info, &fake_uctx);
102         }
103 }
104
105 /* Called from uthread_slim_init() */
106 void init_posix_signals(void)
107 {
108         struct event_queue *posix_sig_ev_q;
109
110         signal_ops = &default_signal_ops;
111         register_ev_handler(EV_POSIX_SIGNAL, handle_event, 0);
112         posix_sig_ev_q = get_eventq(EV_MBOX_UCQ);
113         assert(posix_sig_ev_q);
114         posix_sig_ev_q->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_SPAM_INDIR |
115                                    EVENT_WAKEUP;
116         register_kevent_q(posix_sig_ev_q, EV_POSIX_SIGNAL);
117 }
118
119 /* Swap the contents of two user contexts (not just their pointers). */
120 static void swap_user_contexts(struct user_context *c1, struct user_context *c2)
121 {
122         struct user_context temp_ctx;
123
124         temp_ctx = *c1;
125         *c1 = *c2;
126         *c2 = temp_ctx;
127 }
128
129 /* Helper for checking a stack pointer.  It's possible the context we're
130  * injecting signals into is complete garbage, so using the SP is a little
131  * dangerous. */
132 static bool stack_ptr_is_sane(uintptr_t sp)
133 {
134         if ((sp < PGSIZE) || (sp > ULIM))
135                 return FALSE;
136         return TRUE;
137 }
138
139 static bool uth_is_handling_sigs(struct uthread *uth)
140 {
141         return uth->sigstate.data ? TRUE : FALSE;
142 }
143
144 /* Prep a uthread to run a signal handler.  The original context of the uthread
145  * is saved on its stack, and a new context is set up to run the signal handler
146  * the next time the uthread is run. */
147 static void __prep_sighandler(struct uthread *uthread,
148                               void (*entry)(void),
149                               struct siginfo *info)
150 {
151         uintptr_t stack;
152         struct user_context *ctx;
153
154         if (uthread->flags & UTHREAD_SAVED) {
155                 ctx = &uthread->u_ctx;
156                 stack = get_user_ctx_sp(ctx) - sizeof(struct sigdata);
157                 assert(stack_ptr_is_sane(stack));
158                 uthread->sigstate.data = (struct sigdata*)stack;
159         } else {
160                 assert(current_uthread == uthread);
161                 ctx = &vcpd_of(vcore_id())->uthread_ctx;
162                 stack = get_user_ctx_sp(ctx) - sizeof(struct sigdata);
163                 stack = ROUNDDOWN(stack, __alignof__(struct sigdata));
164                 assert(stack_ptr_is_sane(stack));
165                 uthread->sigstate.data = (struct sigdata*)stack;
166         }
167         /* Parlib aggressively saves the FP state for HW and VM ctxs.  SW ctxs
168          * should not have FP state saved. */
169         switch (uthread->u_ctx.type) {
170         case ROS_HW_CTX:
171         case ROS_VM_CTX:
172                 assert(uthread->flags & UTHREAD_FPSAVED);
173                 /* We need to save the already-saved FP state into the sigstate space.
174                  * The sig handler is taking over the uthread and its GP and FP spaces.
175                  *
176                  * If we ever go back to not aggressively saving the FP state, then for
177                  * HW and VM ctxs, the state is in hardware.  Regardless, we still need
178                  * to save it in ->as, with something like:
179                  *                      save_fp_state(&uthread->sigstate.data->as);
180                  * Either way, when we're done with this entire function, the *uthread*
181                  * will have ~UTHREAD_FPSAVED, since we will be talking about the SW
182                  * context that is running the signal handler. */
183                 uthread->sigstate.data->as = uthread->as;
184                 uthread->flags &= ~UTHREAD_FPSAVED;
185                 break;
186         case ROS_SW_CTX:
187                 assert(!(uthread->flags & UTHREAD_FPSAVED));
188                 break;
189         };
190         if (info != NULL)
191                 uthread->sigstate.data->info = *info;
192
193         init_user_ctx(&uthread->sigstate.data->u_ctx, (uintptr_t)entry, stack);
194         /* The uthread may or may not be UTHREAD_SAVED.  That depends on whether the
195          * uthread was in that state initially.  We're swapping into the location of
196          * 'ctx', which is either in VCPD or the uth itself. */
197         swap_user_contexts(ctx, &uthread->sigstate.data->u_ctx);
198 }
199
200 /* Restore the context saved as the result of running a signal handler on a
201  * uthread. This context will execute the next time the uthread is run. */
202 static void __restore_after_sighandler(struct uthread *uthread)
203 {
204         uthread->u_ctx = uthread->sigstate.data->u_ctx;
205         uthread->flags |= UTHREAD_SAVED;
206         switch (uthread->u_ctx.type) {
207         case ROS_HW_CTX:
208         case ROS_VM_CTX:
209                 uthread->as = uthread->sigstate.data->as;
210                 uthread->flags |= UTHREAD_FPSAVED;
211                 break;
212         }
213         uthread->sigstate.data = NULL;
214 }
215
216 /* Callback when yielding a pthread after upon completion of a sighandler.  We
217  * didn't save the current context on yeild, but that's ok because here we
218  * restore the original saved context of the pthread and then treat this like a
219  * normal voluntary yield. */
220 static void __exit_sighandler_cb(struct uthread *uthread, void *junk)
221 {
222         __restore_after_sighandler(uthread);
223         uthread_paused(uthread);
224 }
225
226 /* Run a specific sighandler from the top of the sigstate stack. The 'info'
227  * struct is prepopulated before the call is triggered as the result of a
228  * reflected fault. */
229 static void __run_sighandler(void)
230 {
231         struct uthread *uthread = current_uthread;
232         int signo = uthread->sigstate.data->info.si_signo;
233
234         __sigdelset(&uthread->sigstate.pending, signo);
235         trigger_posix_signal(signo, &uthread->sigstate.data->info,
236                              &uthread->sigstate.data->u_ctx);
237         uthread_yield(FALSE, __exit_sighandler_cb, 0);
238 }
239
240 /* Run through all pending sighandlers and trigger them with a NULL info
241  * field. These handlers are triggered as the result of thread directed
242  * signals (i.e. not interprocess signals), and thus don't require individual
243  * 'info' structs. */
244 static void __run_all_sighandlers(void)
245 {
246         struct uthread *uthread = current_uthread;
247         sigset_t andset = uthread->sigstate.pending & (~uthread->sigstate.mask);
248
249         for (int i = 1; i < _NSIG; i++) {
250                 if (__sigismember(&andset, i)) {
251                         __sigdelset(&uthread->sigstate.pending, i);
252                         trigger_posix_signal(i, NULL, &uthread->sigstate.data->u_ctx);
253                 }
254         }
255         uthread_yield(FALSE, __exit_sighandler_cb, 0);
256 }
257
258 int uthread_signal(struct uthread *uthread, int signo)
259 {
260         // Slightly racy with clearing of mask when triggering the signal, but
261         // that's OK, as signals are inherently racy since they don't queue up.
262         return sigaddset(&uthread->sigstate.pending, signo);
263 }
264
265 /* If there are any pending signals, prep the uthread to run it's signal
266  * handler. The next time the uthread is run, it will pop into it's signal
267  * handler context instead of its original saved context. Once the signal
268  * handler is complete, the original context will be restored and restarted. */
269 void uthread_prep_pending_signals(struct uthread *uthread)
270 {
271         if (!uth_is_handling_sigs(uthread) && uthread->sigstate.pending) {
272                 sigset_t andset = uthread->sigstate.pending & (~uthread->sigstate.mask);
273
274                 if (!__sigisemptyset(&andset))
275                         __prep_sighandler(uthread, __run_all_sighandlers, NULL);
276         }
277 }
278
279 /* If the given signal is unmasked, prep the uthread to run it's signal
280  * handler, but don't run it yet. In either case, make the uthread runnable
281  * again. Once the signal handler is complete, the original context will be
282  * restored and restarted. */
283 void uthread_prep_signal_from_fault(struct uthread *uthread,
284                                     int signo, int code, void *addr)
285 {
286         if (!__sigismember(&uthread->sigstate.mask, signo)) {
287                 struct siginfo info = {0};
288
289                 if (uth_is_handling_sigs(uthread)) {
290                         printf("Uthread sighandler faulted, signal: %d\n", signo);
291                         /* uthread.c already copied out the faulting ctx into the uth */
292                         print_user_context(&uthread->u_ctx);
293                         exit(-1);
294                 }
295                 info.si_signo = signo;
296                 info.si_code = code;
297                 info.si_addr = addr;
298                 __prep_sighandler(uthread, __run_sighandler, &info);
299         }
300 }
301
302 /* This is managed by vcore / 2LS code */
303 static int __sigaltstack(__const struct sigaltstack *__restrict __ss,
304                          struct sigaltstack *__restrict __oss)
305 {
306         return 0;
307 }
308
309 /* Akaros can't have signals interrupt syscalls to need a restart, though we can
310  * re-wake-up the process while it is waiting for its syscall. */
311 static int __siginterrupt(int __sig, int __interrupt)
312 {
313         return 0;
314 }
315
316 /* Not really possible or relevant - you'd need to walk/examine the event UCQ */
317 static int __sigpending(sigset_t *__set)
318 {
319         return 0;
320 }
321
322 static int __sigprocmask(int __how, __const sigset_t *__restrict __set,
323                          sigset_t *__restrict __oset)
324 {
325         sigset_t *sigmask;
326
327         /* Signal handlers might call sigprocmask, with the intent of affecting the
328          * uthread's sigmask.  Process-wide signal handlers run on behalf of the
329          * entire process and aren't bound to a uthread, which means sigprocmask
330          * won't work.  We can tell we're running one of these handlers since we are
331          * in vcore context.  Uthread signals (e.g. pthread_kill()) run from uthread
332          * context. */
333         if (in_vcore_context()) {
334                 errno = ENOENT;
335                 return -1;
336         }
337
338         sigmask = &current_uthread->sigstate.mask;
339
340         if (__set && (__how != SIG_BLOCK) &&
341                      (__how != SIG_SETMASK) &&
342                      (__how != SIG_UNBLOCK)) {
343                 errno = EINVAL;
344                 return -1;
345         }
346
347         if (__oset)
348                 *__oset = *sigmask;
349         if (__set) {
350                 switch (__how) {
351                         case SIG_BLOCK:
352                                 *sigmask = *sigmask | *__set;
353                                 break;
354                         case SIG_SETMASK:
355                                 *sigmask = *__set;
356                                 break;
357                         case SIG_UNBLOCK:
358                                 *sigmask = *sigmask & ~(*__set);
359                                 break;
360                 }
361         }
362         return 0;
363 }
364
365 /* Needs support with trigger_posix_signal to deal with passing values with
366  * POSIX signals. */
367 static int __sigqueue(__pid_t __pid, int __sig, __const union sigval __val)
368 {
369         return 0;
370 }
371
372 /* Linux specific, and not really needed for us */
373 static int __sigreturn(struct sigcontext *__scp)
374 {
375         return 0;
376 }
377
378 /* This is managed by vcore / 2LS code */
379 static int __sigstack(struct sigstack *__ss, struct sigstack *__oss)
380 {
381         return 0;
382 }
383
384 /* Could do this with a loop on delivery of the signal, sleeping and getting
385  * woken up by the kernel on any event, like we do with async syscalls. */
386 static int __sigsuspend(__const sigset_t *__set)
387 {
388         return 0;
389 }
390
391 /* Can be done similar to sigsuspend, with an extra alarm syscall */
392 static int __sigtimedwait(__const sigset_t *__restrict __set,
393                           siginfo_t *__restrict __info,
394                           __const struct timespec *__restrict __timeout)
395 {
396         return 0;
397 }
398
399 /* Can be done similar to sigsuspend */
400 static int __sigwait(__const sigset_t *__restrict __set, int *__restrict __sig)
401 {
402         return 0;
403 }
404
405 /* Can be done similar to sigsuspend */
406 static int __sigwaitinfo(__const sigset_t *__restrict __set,
407                          siginfo_t *__restrict __info)
408 {
409         return 0;
410 }
411
412 static int __sigself(int signo)
413 {
414         int ret;
415
416         if (in_vcore_context())
417                 return kill(getpid(), signo);
418
419         ret = uthread_signal(current_uthread, signo);
420
421         void cb(struct uthread *uthread, void *arg)
422         {
423                 uthread_paused(uthread);
424         }
425         if (ret == 0)
426                 uthread_yield(TRUE, cb, 0);
427         return ret;
428 }