^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2004 PathScale, Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <stdarg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <strings.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <as-layout.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <kern_util.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <os.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <sysdep/mcontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <um_malloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sys/ucontext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) [SIGTRAP] = relay_signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) [SIGFPE] = relay_signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) [SIGILL] = relay_signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) [SIGWINCH] = winch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) [SIGBUS] = bus_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) [SIGSEGV] = segv_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) [SIGIO] = sigio_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct uml_pt_regs r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int save_errno = errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) r.is_user = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (sig == SIGSEGV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* For segfaults, we want the data from the sigcontext. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) get_regs_from_mc(&r, mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) GET_FAULTINFO_FROM_MC(r.faultinfo, mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* enable signals if sig isn't IRQ signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if ((sig != SIGIO) && (sig != SIGWINCH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unblock_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) (*sig_info[sig])(sig, si, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) errno = save_errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * These are the asynchronous signals. SIGPROF is excluded because we want to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * be able to profile all of UML, not just the non-critical sections. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * profiling is not thread-safe, then that is not my problem. We can disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * profiling when SMP is enabled in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SIGIO_BIT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SIGIO_MASK (1 << SIGIO_BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SIGALRM_BIT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define SIGALRM_MASK (1 << SIGALRM_BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int signals_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static unsigned int signals_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static unsigned int signals_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) enabled = signals_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (!enabled && (sig == SIGIO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) signals_pending |= SIGIO_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) block_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) sig_handler_common(sig, si, mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) set_signals_trace(enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static void timer_real_alarm_handler(mcontext_t *mc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct uml_pt_regs regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (mc != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) get_regs_from_mc(®s, mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) memset(®s, 0, sizeof(regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) timer_handler(SIGALRM, NULL, ®s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) enabled = signals_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (!signals_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) signals_pending |= SIGALRM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) block_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) signals_active |= SIGALRM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) timer_real_alarm_handler(mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) signals_active &= ~SIGALRM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) set_signals_trace(enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) void deliver_alarm(void) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) timer_alarm_handler(SIGALRM, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) void timer_set_signal_handler(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) set_handler(SIGALRM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) void set_sigstack(void *sig_stack, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) stack_t stack = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .ss_flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .ss_sp = sig_stack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .ss_size = size - sizeof(void *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (sigaltstack(&stack, NULL) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) panic("enabling signal stack failed, errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) [SIGSEGV] = sig_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) [SIGBUS] = sig_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) [SIGILL] = sig_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) [SIGFPE] = sig_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) [SIGTRAP] = sig_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) [SIGIO] = sig_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) [SIGWINCH] = sig_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) [SIGALRM] = timer_alarm_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static void hard_handler(int sig, siginfo_t *si, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ucontext_t *uc = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mcontext_t *mc = &uc->uc_mcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) unsigned long pending = 1UL << sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int nested, bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * pending comes back with one bit set for each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * interrupt that arrived while setting up the stack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * plus a bit for this interrupt, plus the zero bit is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * set if this is a nested interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * If bail is true, then we interrupted another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * handler setting up the stack. In this case, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * have to return, and the upper handler will deal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * with this interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) bail = to_irq_stack(&pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (bail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) nested = pending & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pending &= ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) while ((sig = ffs(pending)) != 0){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) sig--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) pending &= ~(1 << sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) (*handlers[sig])(sig, (struct siginfo *)si, mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * Again, pending comes back with a mask of signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * that arrived while tearing down the stack. If this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * is non-zero, we just go back, set up the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * again, and handle the new interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (!nested)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) pending = from_irq_stack(nested);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) } while (pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) void set_handler(int sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct sigaction action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int flags = SA_SIGINFO | SA_ONSTACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) sigset_t sig_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) action.sa_sigaction = hard_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* block irq ones */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) sigemptyset(&action.sa_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) sigaddset(&action.sa_mask, SIGIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) sigaddset(&action.sa_mask, SIGWINCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) sigaddset(&action.sa_mask, SIGALRM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (sig == SIGSEGV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) flags |= SA_NODEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (sigismember(&action.sa_mask, sig))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) flags |= SA_RESTART; /* if it's an irq signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) action.sa_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) action.sa_restorer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (sigaction(sig, &action, NULL) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) panic("sigaction failed - errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) sigemptyset(&sig_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) sigaddset(&sig_mask, sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) panic("sigprocmask failed - errno = %d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int change_sig(int signal, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sigset_t sigset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) sigemptyset(&sigset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) sigaddset(&sigset, signal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, NULL) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) void block_signals(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) signals_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * This must return with signals disabled, so this barrier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * ensures that writes are flushed out before the return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * This might matter if gcc figures out how to inline this and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * decides to shuffle this code into the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) void unblock_signals(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int save_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (signals_enabled == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) signals_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * We loop because the IRQ handler returns with interrupts off. So,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * interrupts may have arrived and we need to re-enable them and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * recheck signals_pending.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * Save and reset save_pending after enabling signals. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * way, signals_pending won't be changed while we're reading it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * Setting signals_enabled and reading signals_pending must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * happen in this order, so have the barrier here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) save_pending = signals_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (save_pending == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) signals_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * We have pending interrupts, so disable signals, as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * handlers expect them off when they are called. They will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * be enabled again above. We need to trace this, as we're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * expected to be enabling interrupts already, but any more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * tracing that happens inside the handlers we call for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * pending signals will mess up the tracing state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) signals_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) um_trace_signals_off();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * Deal with SIGIO first because the alarm handler might
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * schedule, leaving the pending SIGIO stranded until we come
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * back here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * SIGIO's handler doesn't use siginfo or mcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * so they can be NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (save_pending & SIGIO_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sig_handler_common(SIGIO, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* Do not reenter the handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if ((save_pending & SIGALRM_MASK) && (!(signals_active & SIGALRM_MASK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) timer_real_alarm_handler(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* Rerun the loop only if there is still pending SIGIO and not in TIMER handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!(signals_pending & SIGIO_MASK) && (signals_active & SIGALRM_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Re-enable signals and trace that we're doing so. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) um_trace_signals_on();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) signals_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int get_signals(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return signals_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int set_signals(int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (signals_enabled == enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ret = signals_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) unblock_signals();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) else block_signals();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int set_signals_trace(int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (signals_enabled == enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ret = signals_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) unblock_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) block_signals_trace();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int os_is_signal_stack(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) stack_t ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) sigaltstack(NULL, &ss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return ss.ss_flags & SS_ONSTACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }