1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
4 * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
5 * Copyright (C) 2004 PathScale, Inc
6 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
15 #include <as-layout.h>
16 #include <kern_util.h>
18 #include <sysdep/mcontext.h>
19 #include <um_malloc.h>
20 #include <sys/ucontext.h>
21 #include <timetravel.h>
23 void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
24 [SIGTRAP] = relay_signal,
25 [SIGFPE] = relay_signal,
26 [SIGILL] = relay_signal,
28 [SIGBUS] = bus_handler,
29 [SIGSEGV] = segv_handler,
30 [SIGIO] = sigio_handler,
33 static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
36 int save_errno = errno;
40 /* For segfaults, we want the data from the sigcontext. */
41 get_regs_from_mc(&r, mc);
42 GET_FAULTINFO_FROM_MC(r.faultinfo, mc);
45 /* enable signals if sig isn't IRQ signal */
46 if ((sig != SIGIO) && (sig != SIGWINCH))
47 unblock_signals_trace();
49 (*sig_info[sig])(sig, si, &r);
55 * These are the asynchronous signals. SIGPROF is excluded because we want to
56 * be able to profile all of UML, not just the non-critical sections. If
57 * profiling is not thread-safe, then that is not my problem. We can disable
58 * profiling when SMP is enabled in that case.
61 #define SIGIO_MASK (1 << SIGIO_BIT)
64 #define SIGALRM_MASK (1 << SIGALRM_BIT)
67 #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
68 static int signals_blocked;
70 #define signals_blocked 0
72 static unsigned int signals_pending;
73 static unsigned int signals_active = 0;
75 void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
77 int enabled = signals_enabled;
79 if ((signals_blocked || !enabled) && (sig == SIGIO)) {
81 * In TT_MODE_EXTERNAL, need to still call time-travel
82 * handlers unless signals are also blocked for the
83 * external time message processing. This will mark
84 * signals_pending by itself (only if necessary.)
86 if (!signals_blocked && time_travel_mode == TT_MODE_EXTERNAL)
87 sigio_run_timetravel_handlers();
89 signals_pending |= SIGIO_MASK;
93 block_signals_trace();
95 sig_handler_common(sig, si, mc);
97 um_set_signals_trace(enabled);
100 static void timer_real_alarm_handler(mcontext_t *mc)
102 struct uml_pt_regs regs;
105 get_regs_from_mc(®s, mc);
107 memset(®s, 0, sizeof(regs));
108 timer_handler(SIGALRM, NULL, ®s);
111 void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
115 enabled = signals_enabled;
116 if (!signals_enabled) {
117 signals_pending |= SIGALRM_MASK;
121 block_signals_trace();
123 signals_active |= SIGALRM_MASK;
125 timer_real_alarm_handler(mc);
127 signals_active &= ~SIGALRM_MASK;
129 um_set_signals_trace(enabled);
132 void deliver_alarm(void) {
133 timer_alarm_handler(SIGALRM, NULL, NULL);
136 void timer_set_signal_handler(void)
138 set_handler(SIGALRM);
141 void set_sigstack(void *sig_stack, int size)
149 if (sigaltstack(&stack, NULL) != 0)
150 panic("enabling signal stack failed, errno = %d\n", errno);
153 static void sigusr1_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
158 void register_pm_wake_signal(void)
160 set_handler(SIGUSR1);
163 static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = {
164 [SIGSEGV] = sig_handler,
165 [SIGBUS] = sig_handler,
166 [SIGILL] = sig_handler,
167 [SIGFPE] = sig_handler,
168 [SIGTRAP] = sig_handler,
170 [SIGIO] = sig_handler,
171 [SIGWINCH] = sig_handler,
172 [SIGALRM] = timer_alarm_handler,
174 [SIGUSR1] = sigusr1_handler,
177 static void hard_handler(int sig, siginfo_t *si, void *p)
180 mcontext_t *mc = &uc->uc_mcontext;
181 unsigned long pending = 1UL << sig;
187 * pending comes back with one bit set for each
188 * interrupt that arrived while setting up the stack,
189 * plus a bit for this interrupt, plus the zero bit is
190 * set if this is a nested interrupt.
191 * If bail is true, then we interrupted another
192 * handler setting up the stack. In this case, we
193 * have to return, and the upper handler will deal
194 * with this interrupt.
196 bail = to_irq_stack(&pending);
200 nested = pending & 1;
203 while ((sig = ffs(pending)) != 0){
205 pending &= ~(1 << sig);
206 (*handlers[sig])(sig, (struct siginfo *)si, mc);
210 * Again, pending comes back with a mask of signals
211 * that arrived while tearing down the stack. If this
212 * is non-zero, we just go back, set up the stack
213 * again, and handle the new interrupts.
216 pending = from_irq_stack(nested);
220 void set_handler(int sig)
222 struct sigaction action;
223 int flags = SA_SIGINFO | SA_ONSTACK;
226 action.sa_sigaction = hard_handler;
229 sigemptyset(&action.sa_mask);
230 sigaddset(&action.sa_mask, SIGIO);
231 sigaddset(&action.sa_mask, SIGWINCH);
232 sigaddset(&action.sa_mask, SIGALRM);
237 if (sigismember(&action.sa_mask, sig))
238 flags |= SA_RESTART; /* if it's an irq signal */
240 action.sa_flags = flags;
241 action.sa_restorer = NULL;
242 if (sigaction(sig, &action, NULL) < 0)
243 panic("sigaction failed - errno = %d\n", errno);
245 sigemptyset(&sig_mask);
246 sigaddset(&sig_mask, sig);
247 if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
248 panic("sigprocmask failed - errno = %d\n", errno);
251 void send_sigio_to_self(void)
253 kill(os_getpid(), SIGIO);
256 int change_sig(int signal, int on)
260 sigemptyset(&sigset);
261 sigaddset(&sigset, signal);
262 if (sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, NULL) < 0)
268 void block_signals(void)
272 * This must return with signals disabled, so this barrier
273 * ensures that writes are flushed out before the return.
274 * This might matter if gcc figures out how to inline this and
275 * decides to shuffle this code into the caller.
280 void unblock_signals(void)
284 if (signals_enabled == 1)
288 #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
289 deliver_time_travel_irqs();
293 * We loop because the IRQ handler returns with interrupts off. So,
294 * interrupts may have arrived and we need to re-enable them and
295 * recheck signals_pending.
299 * Save and reset save_pending after enabling signals. This
300 * way, signals_pending won't be changed while we're reading it.
302 * Setting signals_enabled and reading signals_pending must
303 * happen in this order, so have the barrier here.
307 save_pending = signals_pending;
308 if (save_pending == 0)
314 * We have pending interrupts, so disable signals, as the
315 * handlers expect them off when they are called. They will
316 * be enabled again above. We need to trace this, as we're
317 * expected to be enabling interrupts already, but any more
318 * tracing that happens inside the handlers we call for the
319 * pending signals will mess up the tracing state.
322 um_trace_signals_off();
325 * Deal with SIGIO first because the alarm handler might
326 * schedule, leaving the pending SIGIO stranded until we come
329 * SIGIO's handler doesn't use siginfo or mcontext,
330 * so they can be NULL.
332 if (save_pending & SIGIO_MASK)
333 sig_handler_common(SIGIO, NULL, NULL);
335 /* Do not reenter the handler */
337 if ((save_pending & SIGALRM_MASK) && (!(signals_active & SIGALRM_MASK)))
338 timer_real_alarm_handler(NULL);
340 /* Rerun the loop only if there is still pending SIGIO and not in TIMER handler */
342 if (!(signals_pending & SIGIO_MASK) && (signals_active & SIGALRM_MASK))
345 /* Re-enable signals and trace that we're doing so. */
346 um_trace_signals_on();
351 int um_set_signals(int enable)
354 if (signals_enabled == enable)
357 ret = signals_enabled;
360 else block_signals();
365 int um_set_signals_trace(int enable)
368 if (signals_enabled == enable)
371 ret = signals_enabled;
373 unblock_signals_trace();
375 block_signals_trace();
380 #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
381 void mark_sigio_pending(void)
383 signals_pending |= SIGIO_MASK;
386 void block_signals_hard(void)
394 void unblock_signals_hard(void)
396 if (!signals_blocked)
398 /* Must be set to 0 before we check the pending bits etc. */
402 if (signals_pending && signals_enabled) {
403 /* this is a bit inefficient, but that's not really important */
406 } else if (signals_pending & SIGIO_MASK) {
407 /* we need to run time-travel handlers even if not enabled */
408 sigio_run_timetravel_handlers();
413 int os_is_signal_stack(void)
416 sigaltstack(NULL, &ss);
418 return ss.ss_flags & SS_ONSTACK;