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.
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.
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. */
27 // Needed for sigmask functions...
31 #include <parlib/parlib.h>
32 #include <parlib/signal.h>
33 #include <parlib/uthread.h>
34 #include <parlib/event.h>
36 #include <parlib/assert.h>
37 #include <ros/procinfo.h>
38 #include <ros/syscall.h>
40 #include <parlib/stdio.h>
42 /* Forward declare our signal_ops functions. */
43 static int __sigaltstack(__const struct sigaltstack *__restrict __ss,
44 struct sigaltstack *__restrict __oss);
45 static int __siginterrupt(int __sig, int __interrupt);
46 static int __sigpending(sigset_t *__set);
47 static int __sigprocmask(int __how, __const sigset_t *__restrict __set,
48 sigset_t *__restrict __oset);
49 static int __sigqueue(__pid_t __pid, int __sig, __const union sigval __val);
50 static int __sigreturn(struct sigcontext *__scp);
51 static int __sigstack(struct sigstack *__ss, struct sigstack *__oss);
52 static int __sigsuspend(__const sigset_t *__set);
53 static int __sigtimedwait(__const sigset_t *__restrict __set,
54 siginfo_t *__restrict __info,
55 __const struct timespec *__restrict __timeout);
56 static int __sigwait(__const sigset_t *__restrict __set, int *__restrict __sig);
57 static int __sigwaitinfo(__const sigset_t *__restrict __set,
58 siginfo_t *__restrict __info);
59 static int __sigself(int signo);
61 /* The default definition of signal_ops (similar to sched_ops in uthread.c) */
62 struct signal_ops default_signal_ops = {
63 .sigaltstack = __sigaltstack,
64 .siginterrupt = __siginterrupt,
65 .sigpending = __sigpending,
66 .sigprocmask = __sigprocmask,
67 .sigqueue = __sigqueue,
68 .sigreturn = __sigreturn,
69 .sigstack = __sigstack,
70 .sigsuspend = __sigsuspend,
71 .sigtimedwait = __sigtimedwait,
73 .sigwaitinfo = __sigwaitinfo,
77 /* This is the catch all akaros event->posix signal handler. All posix signals
78 * are received in a single akaros event type. They are then dispatched from
79 * this function to their proper posix signal handler */
80 static void handle_event(struct event_msg *ev_msg, unsigned int ev_type,
84 struct siginfo info = {0};
85 info.si_code = SI_USER;
88 sig_nr = ev_msg->ev_arg1;
89 trigger_posix_signal(sig_nr, &info, 0);
92 /* Called from uthread_slim_init() */
93 void init_posix_signals(void)
95 struct event_queue *posix_sig_ev_q;
97 signal_ops = &default_signal_ops;
98 register_ev_handler(EV_POSIX_SIGNAL, handle_event, 0);
99 posix_sig_ev_q = get_eventq(EV_MBOX_UCQ);
100 assert(posix_sig_ev_q);
101 posix_sig_ev_q->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_SPAM_INDIR |
103 register_kevent_q(posix_sig_ev_q, EV_POSIX_SIGNAL);
106 /* Swap the contents of two user contexts (not just their pointers). */
107 static void swap_user_contexts(struct user_context *c1, struct user_context *c2)
109 struct user_context temp_ctx;
116 /* Prep a to run a signal handler. The original context of the uthread
117 * is saved on its stack, and a new context is set up to run the signal
118 * handler the next time the uthread is run. */
119 static void __prep_sighandler(struct uthread *uthread,
121 struct siginfo *info)
124 struct user_context *ctx;
126 if (uthread->flags & UTHREAD_SAVED) {
127 ctx = &uthread->u_ctx;
128 stack = get_user_ctx_stack(ctx) - sizeof(struct sigdata);
129 uthread->sigstate.data = (struct sigdata*)stack;
130 if (uthread->flags & UTHREAD_FPSAVED) {
131 uthread->sigstate.data->as = uthread->as;
132 uthread->flags &= ~UTHREAD_FPSAVED;
135 assert(current_uthread == uthread);
136 ctx = &vcpd_of(vcore_id())->uthread_ctx;
137 stack = get_user_ctx_stack(ctx) - sizeof(struct sigdata);
138 uthread->sigstate.data = (struct sigdata*)stack;
139 save_fp_state(&uthread->sigstate.data->as);
142 uthread->sigstate.data->info = *info;
144 init_user_ctx(&uthread->sigstate.data->u_ctx, (uintptr_t)entry, stack);
145 swap_user_contexts(ctx, &uthread->sigstate.data->u_ctx);
148 /* Restore the context saved as the result of running a signal handler on a
149 * uthread. This context will execute the next time the uthread is run. */
150 static void __restore_after_sighandler(struct uthread *uthread)
152 uthread->u_ctx = uthread->sigstate.data->u_ctx;
153 uthread->flags |= UTHREAD_SAVED;
154 switch (uthread->u_ctx.type) {
157 uthread->as = uthread->sigstate.data->as;
158 uthread->flags |= UTHREAD_FPSAVED;
161 uthread->sigstate.data = NULL;
164 /* Callback when yielding a pthread after upon completion of a sighandler. We
165 * didn't save the current context on yeild, but that's ok because here we
166 * restore the original saved context of the pthread and then treat this like a
167 * normal voluntary yield. */
168 static void __exit_sighandler_cb(struct uthread *uthread, void *junk)
170 __restore_after_sighandler(uthread);
171 uthread_paused(uthread);
174 /* Run a specific sighandler from the top of the sigstate stack. The 'info'
175 * struct is prepopulated before the call is triggered as the result of a
176 * reflected fault. */
177 static void __run_sighandler(void)
179 struct uthread *uthread = current_uthread;
180 int signo = uthread->sigstate.data->info.si_signo;
182 __sigdelset(&uthread->sigstate.pending, signo);
183 trigger_posix_signal(signo, &uthread->sigstate.data->info,
184 &uthread->sigstate.data->u_ctx);
185 uthread_yield(FALSE, __exit_sighandler_cb, 0);
188 /* Run through all pending sighandlers and trigger them with a NULL info
189 * field. These handlers are triggered as the result of thread directed
190 * signals (i.e. not interprocess signals), and thus don't require individual
192 static void __run_all_sighandlers(void)
194 struct uthread *uthread = current_uthread;
195 sigset_t andset = uthread->sigstate.pending & (~uthread->sigstate.mask);
197 for (int i = 1; i < _NSIG; i++) {
198 if (__sigismember(&andset, i)) {
199 __sigdelset(&uthread->sigstate.pending, i);
200 trigger_posix_signal(i, NULL, &uthread->sigstate.data->u_ctx);
203 uthread_yield(FALSE, __exit_sighandler_cb, 0);
206 int uthread_signal(struct uthread *uthread, int signo)
208 // Slightly racy with clearing of mask when triggering the signal, but
209 // that's OK, as signals are inherently racy since they don't queue up.
210 return sigaddset(&uthread->sigstate.pending, signo);
213 /* If there are any pending signals, prep the uthread to run it's signal
214 * handler. The next time the uthread is run, it will pop into it's signal
215 * handler context instead of its original saved context. Once the signal
216 * handler is complete, the original context will be restored and restarted. */
217 void uthread_prep_pending_signals(struct uthread *uthread)
219 if (!uthread->sigstate.data && uthread->sigstate.pending) {
220 sigset_t andset = uthread->sigstate.pending & (~uthread->sigstate.mask);
222 if (!__sigisemptyset(&andset))
223 __prep_sighandler(uthread, __run_all_sighandlers, NULL);
227 /* If the given signal is unmasked, prep the uthread to run it's signal
228 * handler, but don't run it yet. In either case, make the uthread runnable
229 * again. Once the signal handler is complete, the original context will be
230 * restored and restarted. */
231 void uthread_prep_signal_from_fault(struct uthread *uthread,
232 int signo, int code, void *addr)
234 if (!__sigismember(&uthread->sigstate.mask, signo)) {
235 struct siginfo info = {0};
237 if (uthread->sigstate.data) {
238 printf("Uthread sighandler faulted, signal: %d\n", signo);
239 /* uthread.c already copied out the faulting ctx into the uth */
240 print_user_context(&uthread->u_ctx);
243 info.si_signo = signo;
246 __prep_sighandler(uthread, __run_sighandler, &info);
250 /* This is managed by vcore / 2LS code */
251 static int __sigaltstack(__const struct sigaltstack *__restrict __ss,
252 struct sigaltstack *__restrict __oss)
257 /* Akaros can't have signals interrupt syscalls to need a restart, though we can
258 * re-wake-up the process while it is waiting for its syscall. */
259 static int __siginterrupt(int __sig, int __interrupt)
264 /* Not really possible or relevant - you'd need to walk/examine the event UCQ */
265 static int __sigpending(sigset_t *__set)
270 static int __sigprocmask(int __how, __const sigset_t *__restrict __set,
271 sigset_t *__restrict __oset)
273 sigset_t *sigmask = ¤t_uthread->sigstate.mask;
275 if (__set && (__how != SIG_BLOCK) &&
276 (__how != SIG_SETMASK) &&
277 (__how != SIG_UNBLOCK)) {
287 *sigmask = *sigmask | *__set;
293 *sigmask = *sigmask & ~(*__set);
300 /* Needs support with trigger_posix_signal to deal with passing values with
302 static int __sigqueue(__pid_t __pid, int __sig, __const union sigval __val)
307 /* Linux specific, and not really needed for us */
308 static int __sigreturn(struct sigcontext *__scp)
313 /* This is managed by vcore / 2LS code */
314 static int __sigstack(struct sigstack *__ss, struct sigstack *__oss)
319 /* Could do this with a loop on delivery of the signal, sleeping and getting
320 * woken up by the kernel on any event, like we do with async syscalls. */
321 static int __sigsuspend(__const sigset_t *__set)
326 /* Can be done similar to sigsuspend, with an extra alarm syscall */
327 static int __sigtimedwait(__const sigset_t *__restrict __set,
328 siginfo_t *__restrict __info,
329 __const struct timespec *__restrict __timeout)
334 /* Can be done similar to sigsuspend */
335 static int __sigwait(__const sigset_t *__restrict __set, int *__restrict __sig)
340 /* Can be done similar to sigsuspend */
341 static int __sigwaitinfo(__const sigset_t *__restrict __set,
342 siginfo_t *__restrict __info)
347 static int __sigself(int signo)
349 int ret = uthread_signal(current_uthread, signo);
351 void cb(struct uthread *uthread, void *arg)
353 uthread_paused(uthread);
356 uthread_yield(TRUE, cb, 0);