Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
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)
7 : */
8 :
9 : #include <stdlib.h>
10 : #include <stdarg.h>
11 : #include <errno.h>
12 : #include <signal.h>
13 : #include <string.h>
14 : #include <strings.h>
15 : #include <as-layout.h>
16 : #include <kern_util.h>
17 : #include <os.h>
18 : #include <sysdep/mcontext.h>
19 : #include <um_malloc.h>
20 : #include <sys/ucontext.h>
21 : #include <timetravel.h>
22 :
23 : void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
24 : [SIGTRAP] = relay_signal,
25 : [SIGFPE] = relay_signal,
26 : [SIGILL] = relay_signal,
27 : [SIGWINCH] = winch,
28 : [SIGBUS] = bus_handler,
29 : [SIGSEGV] = segv_handler,
30 : [SIGIO] = sigio_handler,
31 : };
32 :
33 0 : static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
34 : {
35 : struct uml_pt_regs r;
36 0 : int save_errno = errno;
37 :
38 0 : r.is_user = 0;
39 0 : if (sig == SIGSEGV) {
40 : /* For segfaults, we want the data from the sigcontext. */
41 0 : get_regs_from_mc(&r, mc);
42 0 : GET_FAULTINFO_FROM_MC(r.faultinfo, mc);
43 : }
44 :
45 : /* enable signals if sig isn't IRQ signal */
46 0 : if ((sig != SIGIO) && (sig != SIGWINCH))
47 0 : unblock_signals_trace();
48 :
49 0 : (*sig_info[sig])(sig, si, &r);
50 :
51 0 : errno = save_errno;
52 0 : }
53 :
54 : /*
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.
59 : */
60 : #define SIGIO_BIT 0
61 : #define SIGIO_MASK (1 << SIGIO_BIT)
62 :
63 : #define SIGALRM_BIT 1
64 : #define SIGALRM_MASK (1 << SIGALRM_BIT)
65 :
66 : int signals_enabled;
67 : #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
68 : static int signals_blocked;
69 : #else
70 : #define signals_blocked 0
71 : #endif
72 : static unsigned int signals_pending;
73 : static unsigned int signals_active = 0;
74 :
75 0 : void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
76 : {
77 0 : int enabled = signals_enabled;
78 :
79 0 : if ((signals_blocked || !enabled) && (sig == SIGIO)) {
80 : /*
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.)
85 : */
86 : if (!signals_blocked && time_travel_mode == TT_MODE_EXTERNAL)
87 : sigio_run_timetravel_handlers();
88 : else
89 0 : signals_pending |= SIGIO_MASK;
90 0 : return;
91 : }
92 :
93 0 : block_signals_trace();
94 :
95 0 : sig_handler_common(sig, si, mc);
96 :
97 0 : um_set_signals_trace(enabled);
98 : }
99 :
100 5 : static void timer_real_alarm_handler(mcontext_t *mc)
101 : {
102 : struct uml_pt_regs regs;
103 :
104 5 : if (mc != NULL)
105 5 : get_regs_from_mc(®s, mc);
106 : else
107 0 : memset(®s, 0, sizeof(regs));
108 5 : timer_handler(SIGALRM, NULL, ®s);
109 5 : }
110 :
111 5 : void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
112 : {
113 : int enabled;
114 :
115 5 : enabled = signals_enabled;
116 5 : if (!signals_enabled) {
117 0 : signals_pending |= SIGALRM_MASK;
118 0 : return;
119 : }
120 :
121 5 : block_signals_trace();
122 :
123 5 : signals_active |= SIGALRM_MASK;
124 :
125 5 : timer_real_alarm_handler(mc);
126 :
127 5 : signals_active &= ~SIGALRM_MASK;
128 :
129 5 : um_set_signals_trace(enabled);
130 : }
131 :
132 0 : void deliver_alarm(void) {
133 0 : timer_alarm_handler(SIGALRM, NULL, NULL);
134 0 : }
135 :
136 1 : void timer_set_signal_handler(void)
137 : {
138 1 : set_handler(SIGALRM);
139 1 : }
140 :
141 1 : void set_sigstack(void *sig_stack, int size)
142 : {
143 1 : stack_t stack = {
144 : .ss_flags = 0,
145 : .ss_sp = sig_stack,
146 : .ss_size = size
147 : };
148 :
149 1 : if (sigaltstack(&stack, NULL) != 0)
150 0 : panic("enabling signal stack failed, errno = %d\n", errno);
151 1 : }
152 :
153 0 : static void sigusr1_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
154 : {
155 0 : uml_pm_wake();
156 0 : }
157 :
158 1 : void register_pm_wake_signal(void)
159 : {
160 1 : set_handler(SIGUSR1);
161 1 : }
162 :
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,
169 :
170 : [SIGIO] = sig_handler,
171 : [SIGWINCH] = sig_handler,
172 : [SIGALRM] = timer_alarm_handler,
173 :
174 : [SIGUSR1] = sigusr1_handler,
175 : };
176 :
177 5 : static void hard_handler(int sig, siginfo_t *si, void *p)
178 : {
179 5 : ucontext_t *uc = p;
180 5 : mcontext_t *mc = &uc->uc_mcontext;
181 5 : unsigned long pending = 1UL << sig;
182 :
183 : do {
184 : int nested, bail;
185 :
186 : /*
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.
195 : */
196 5 : bail = to_irq_stack(&pending);
197 5 : if (bail)
198 0 : return;
199 :
200 5 : nested = pending & 1;
201 5 : pending &= ~1;
202 :
203 15 : while ((sig = ffs(pending)) != 0){
204 5 : sig--;
205 5 : pending &= ~(1 << sig);
206 5 : (*handlers[sig])(sig, (struct siginfo *)si, mc);
207 : }
208 :
209 : /*
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.
214 : */
215 5 : if (!nested)
216 5 : pending = from_irq_stack(nested);
217 5 : } while (pending);
218 : }
219 :
220 9 : void set_handler(int sig)
221 : {
222 : struct sigaction action;
223 9 : int flags = SA_SIGINFO | SA_ONSTACK;
224 : sigset_t sig_mask;
225 :
226 9 : action.sa_sigaction = hard_handler;
227 :
228 : /* block irq ones */
229 9 : sigemptyset(&action.sa_mask);
230 9 : sigaddset(&action.sa_mask, SIGIO);
231 9 : sigaddset(&action.sa_mask, SIGWINCH);
232 9 : sigaddset(&action.sa_mask, SIGALRM);
233 :
234 9 : if (sig == SIGSEGV)
235 1 : flags |= SA_NODEFER;
236 :
237 9 : if (sigismember(&action.sa_mask, sig))
238 3 : flags |= SA_RESTART; /* if it's an irq signal */
239 :
240 9 : action.sa_flags = flags;
241 9 : action.sa_restorer = NULL;
242 9 : if (sigaction(sig, &action, NULL) < 0)
243 0 : panic("sigaction failed - errno = %d\n", errno);
244 :
245 9 : sigemptyset(&sig_mask);
246 9 : sigaddset(&sig_mask, sig);
247 9 : if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
248 0 : panic("sigprocmask failed - errno = %d\n", errno);
249 9 : }
250 :
251 0 : void send_sigio_to_self(void)
252 : {
253 0 : kill(os_getpid(), SIGIO);
254 0 : }
255 :
256 10 : int change_sig(int signal, int on)
257 : {
258 : sigset_t sigset;
259 :
260 10 : sigemptyset(&sigset);
261 10 : sigaddset(&sigset, signal);
262 10 : if (sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, NULL) < 0)
263 0 : return -errno;
264 :
265 : return 0;
266 : }
267 :
268 4677 : void block_signals(void)
269 : {
270 34143 : signals_enabled = 0;
271 : /*
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.
276 : */
277 34143 : barrier();
278 4677 : }
279 :
280 34142 : void unblock_signals(void)
281 : {
282 : int save_pending;
283 :
284 34142 : if (signals_enabled == 1)
285 : return;
286 :
287 34142 : signals_enabled = 1;
288 : #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
289 : deliver_time_travel_irqs();
290 : #endif
291 :
292 : /*
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.
296 : */
297 : while (1) {
298 : /*
299 : * Save and reset save_pending after enabling signals. This
300 : * way, signals_pending won't be changed while we're reading it.
301 : *
302 : * Setting signals_enabled and reading signals_pending must
303 : * happen in this order, so have the barrier here.
304 : */
305 34142 : barrier();
306 :
307 34142 : save_pending = signals_pending;
308 34142 : if (save_pending == 0)
309 : return;
310 :
311 0 : signals_pending = 0;
312 :
313 : /*
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.
320 : */
321 0 : signals_enabled = 0;
322 0 : um_trace_signals_off();
323 :
324 : /*
325 : * Deal with SIGIO first because the alarm handler might
326 : * schedule, leaving the pending SIGIO stranded until we come
327 : * back here.
328 : *
329 : * SIGIO's handler doesn't use siginfo or mcontext,
330 : * so they can be NULL.
331 : */
332 0 : if (save_pending & SIGIO_MASK)
333 0 : sig_handler_common(SIGIO, NULL, NULL);
334 :
335 : /* Do not reenter the handler */
336 :
337 0 : if ((save_pending & SIGALRM_MASK) && (!(signals_active & SIGALRM_MASK)))
338 0 : timer_real_alarm_handler(NULL);
339 :
340 : /* Rerun the loop only if there is still pending SIGIO and not in TIMER handler */
341 :
342 0 : if (!(signals_pending & SIGIO_MASK) && (signals_active & SIGALRM_MASK))
343 : return;
344 :
345 : /* Re-enable signals and trace that we're doing so. */
346 0 : um_trace_signals_on();
347 0 : signals_enabled = 1;
348 : }
349 : }
350 :
351 73806 : int um_set_signals(int enable)
352 : {
353 : int ret;
354 73806 : if (signals_enabled == enable)
355 : return enable;
356 :
357 58932 : ret = signals_enabled;
358 58932 : if (enable)
359 29466 : unblock_signals();
360 : else block_signals();
361 :
362 : return ret;
363 : }
364 :
365 862 : int um_set_signals_trace(int enable)
366 : {
367 : int ret;
368 862 : if (signals_enabled == enable)
369 : return enable;
370 :
371 5 : ret = signals_enabled;
372 5 : if (enable)
373 5 : unblock_signals_trace();
374 : else
375 0 : block_signals_trace();
376 :
377 : return ret;
378 : }
379 :
380 : #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
381 : void mark_sigio_pending(void)
382 : {
383 : signals_pending |= SIGIO_MASK;
384 : }
385 :
386 : void block_signals_hard(void)
387 : {
388 : if (signals_blocked)
389 : return;
390 : signals_blocked = 1;
391 : barrier();
392 : }
393 :
394 : void unblock_signals_hard(void)
395 : {
396 : if (!signals_blocked)
397 : return;
398 : /* Must be set to 0 before we check the pending bits etc. */
399 : signals_blocked = 0;
400 : barrier();
401 :
402 : if (signals_pending && signals_enabled) {
403 : /* this is a bit inefficient, but that's not really important */
404 : block_signals();
405 : unblock_signals();
406 : } else if (signals_pending & SIGIO_MASK) {
407 : /* we need to run time-travel handlers even if not enabled */
408 : sigio_run_timetravel_handlers();
409 : }
410 : }
411 : #endif
412 :
413 1 : int os_is_signal_stack(void)
414 : {
415 : stack_t ss;
416 1 : sigaltstack(NULL, &ss);
417 :
418 1 : return ss.ss_flags & SS_ONSTACK;
419 : }
|