Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
0004  * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
0005  * Copyright (C) 2004 PathScale, Inc
0006  * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
0007  */
0008 
0009 #include <stdlib.h>
0010 #include <stdarg.h>
0011 #include <errno.h>
0012 #include <signal.h>
0013 #include <string.h>
0014 #include <strings.h>
0015 #include <as-layout.h>
0016 #include <kern_util.h>
0017 #include <os.h>
0018 #include <sysdep/mcontext.h>
0019 #include <um_malloc.h>
0020 #include <sys/ucontext.h>
0021 #include <timetravel.h>
0022 
0023 void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
0024     [SIGTRAP]   = relay_signal,
0025     [SIGFPE]    = relay_signal,
0026     [SIGILL]    = relay_signal,
0027     [SIGWINCH]  = winch,
0028     [SIGBUS]    = bus_handler,
0029     [SIGSEGV]   = segv_handler,
0030     [SIGIO]     = sigio_handler,
0031 };
0032 
0033 static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc)
0034 {
0035     struct uml_pt_regs r;
0036     int save_errno = errno;
0037 
0038     r.is_user = 0;
0039     if (sig == SIGSEGV) {
0040         /* For segfaults, we want the data from the sigcontext. */
0041         get_regs_from_mc(&r, mc);
0042         GET_FAULTINFO_FROM_MC(r.faultinfo, mc);
0043     }
0044 
0045     /* enable signals if sig isn't IRQ signal */
0046     if ((sig != SIGIO) && (sig != SIGWINCH))
0047         unblock_signals_trace();
0048 
0049     (*sig_info[sig])(sig, si, &r);
0050 
0051     errno = save_errno;
0052 }
0053 
0054 /*
0055  * These are the asynchronous signals.  SIGPROF is excluded because we want to
0056  * be able to profile all of UML, not just the non-critical sections.  If
0057  * profiling is not thread-safe, then that is not my problem.  We can disable
0058  * profiling when SMP is enabled in that case.
0059  */
0060 #define SIGIO_BIT 0
0061 #define SIGIO_MASK (1 << SIGIO_BIT)
0062 
0063 #define SIGALRM_BIT 1
0064 #define SIGALRM_MASK (1 << SIGALRM_BIT)
0065 
0066 int signals_enabled;
0067 #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
0068 static int signals_blocked;
0069 #else
0070 #define signals_blocked 0
0071 #endif
0072 static unsigned int signals_pending;
0073 static unsigned int signals_active = 0;
0074 
0075 void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
0076 {
0077     int enabled = signals_enabled;
0078 
0079     if ((signals_blocked || !enabled) && (sig == SIGIO)) {
0080         /*
0081          * In TT_MODE_EXTERNAL, need to still call time-travel
0082          * handlers unless signals are also blocked for the
0083          * external time message processing. This will mark
0084          * signals_pending by itself (only if necessary.)
0085          */
0086         if (!signals_blocked && time_travel_mode == TT_MODE_EXTERNAL)
0087             sigio_run_timetravel_handlers();
0088         else
0089             signals_pending |= SIGIO_MASK;
0090         return;
0091     }
0092 
0093     block_signals_trace();
0094 
0095     sig_handler_common(sig, si, mc);
0096 
0097     um_set_signals_trace(enabled);
0098 }
0099 
0100 static void timer_real_alarm_handler(mcontext_t *mc)
0101 {
0102     struct uml_pt_regs regs;
0103 
0104     if (mc != NULL)
0105         get_regs_from_mc(&regs, mc);
0106     else
0107         memset(&regs, 0, sizeof(regs));
0108     timer_handler(SIGALRM, NULL, &regs);
0109 }
0110 
0111 void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
0112 {
0113     int enabled;
0114 
0115     enabled = signals_enabled;
0116     if (!signals_enabled) {
0117         signals_pending |= SIGALRM_MASK;
0118         return;
0119     }
0120 
0121     block_signals_trace();
0122 
0123     signals_active |= SIGALRM_MASK;
0124 
0125     timer_real_alarm_handler(mc);
0126 
0127     signals_active &= ~SIGALRM_MASK;
0128 
0129     um_set_signals_trace(enabled);
0130 }
0131 
0132 void deliver_alarm(void) {
0133     timer_alarm_handler(SIGALRM, NULL, NULL);
0134 }
0135 
0136 void timer_set_signal_handler(void)
0137 {
0138     set_handler(SIGALRM);
0139 }
0140 
0141 void set_sigstack(void *sig_stack, int size)
0142 {
0143     stack_t stack = {
0144         .ss_flags = 0,
0145         .ss_sp = sig_stack,
0146         .ss_size = size
0147     };
0148 
0149     if (sigaltstack(&stack, NULL) != 0)
0150         panic("enabling signal stack failed, errno = %d\n", errno);
0151 }
0152 
0153 static void sigusr1_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
0154 {
0155     uml_pm_wake();
0156 }
0157 
0158 void register_pm_wake_signal(void)
0159 {
0160     set_handler(SIGUSR1);
0161 }
0162 
0163 static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = {
0164     [SIGSEGV] = sig_handler,
0165     [SIGBUS] = sig_handler,
0166     [SIGILL] = sig_handler,
0167     [SIGFPE] = sig_handler,
0168     [SIGTRAP] = sig_handler,
0169 
0170     [SIGIO] = sig_handler,
0171     [SIGWINCH] = sig_handler,
0172     [SIGALRM] = timer_alarm_handler,
0173 
0174     [SIGUSR1] = sigusr1_handler,
0175 };
0176 
0177 static void hard_handler(int sig, siginfo_t *si, void *p)
0178 {
0179     ucontext_t *uc = p;
0180     mcontext_t *mc = &uc->uc_mcontext;
0181     unsigned long pending = 1UL << sig;
0182 
0183     do {
0184         int nested, bail;
0185 
0186         /*
0187          * pending comes back with one bit set for each
0188          * interrupt that arrived while setting up the stack,
0189          * plus a bit for this interrupt, plus the zero bit is
0190          * set if this is a nested interrupt.
0191          * If bail is true, then we interrupted another
0192          * handler setting up the stack.  In this case, we
0193          * have to return, and the upper handler will deal
0194          * with this interrupt.
0195          */
0196         bail = to_irq_stack(&pending);
0197         if (bail)
0198             return;
0199 
0200         nested = pending & 1;
0201         pending &= ~1;
0202 
0203         while ((sig = ffs(pending)) != 0){
0204             sig--;
0205             pending &= ~(1 << sig);
0206             (*handlers[sig])(sig, (struct siginfo *)si, mc);
0207         }
0208 
0209         /*
0210          * Again, pending comes back with a mask of signals
0211          * that arrived while tearing down the stack.  If this
0212          * is non-zero, we just go back, set up the stack
0213          * again, and handle the new interrupts.
0214          */
0215         if (!nested)
0216             pending = from_irq_stack(nested);
0217     } while (pending);
0218 }
0219 
0220 void set_handler(int sig)
0221 {
0222     struct sigaction action;
0223     int flags = SA_SIGINFO | SA_ONSTACK;
0224     sigset_t sig_mask;
0225 
0226     action.sa_sigaction = hard_handler;
0227 
0228     /* block irq ones */
0229     sigemptyset(&action.sa_mask);
0230     sigaddset(&action.sa_mask, SIGIO);
0231     sigaddset(&action.sa_mask, SIGWINCH);
0232     sigaddset(&action.sa_mask, SIGALRM);
0233 
0234     if (sig == SIGSEGV)
0235         flags |= SA_NODEFER;
0236 
0237     if (sigismember(&action.sa_mask, sig))
0238         flags |= SA_RESTART; /* if it's an irq signal */
0239 
0240     action.sa_flags = flags;
0241     action.sa_restorer = NULL;
0242     if (sigaction(sig, &action, NULL) < 0)
0243         panic("sigaction failed - errno = %d\n", errno);
0244 
0245     sigemptyset(&sig_mask);
0246     sigaddset(&sig_mask, sig);
0247     if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
0248         panic("sigprocmask failed - errno = %d\n", errno);
0249 }
0250 
0251 void send_sigio_to_self(void)
0252 {
0253     kill(os_getpid(), SIGIO);
0254 }
0255 
0256 int change_sig(int signal, int on)
0257 {
0258     sigset_t sigset;
0259 
0260     sigemptyset(&sigset);
0261     sigaddset(&sigset, signal);
0262     if (sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, NULL) < 0)
0263         return -errno;
0264 
0265     return 0;
0266 }
0267 
0268 void block_signals(void)
0269 {
0270     signals_enabled = 0;
0271     /*
0272      * This must return with signals disabled, so this barrier
0273      * ensures that writes are flushed out before the return.
0274      * This might matter if gcc figures out how to inline this and
0275      * decides to shuffle this code into the caller.
0276      */
0277     barrier();
0278 }
0279 
0280 void unblock_signals(void)
0281 {
0282     int save_pending;
0283 
0284     if (signals_enabled == 1)
0285         return;
0286 
0287     signals_enabled = 1;
0288 #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
0289     deliver_time_travel_irqs();
0290 #endif
0291 
0292     /*
0293      * We loop because the IRQ handler returns with interrupts off.  So,
0294      * interrupts may have arrived and we need to re-enable them and
0295      * recheck signals_pending.
0296      */
0297     while (1) {
0298         /*
0299          * Save and reset save_pending after enabling signals.  This
0300          * way, signals_pending won't be changed while we're reading it.
0301          *
0302          * Setting signals_enabled and reading signals_pending must
0303          * happen in this order, so have the barrier here.
0304          */
0305         barrier();
0306 
0307         save_pending = signals_pending;
0308         if (save_pending == 0)
0309             return;
0310 
0311         signals_pending = 0;
0312 
0313         /*
0314          * We have pending interrupts, so disable signals, as the
0315          * handlers expect them off when they are called.  They will
0316          * be enabled again above. We need to trace this, as we're
0317          * expected to be enabling interrupts already, but any more
0318          * tracing that happens inside the handlers we call for the
0319          * pending signals will mess up the tracing state.
0320          */
0321         signals_enabled = 0;
0322         um_trace_signals_off();
0323 
0324         /*
0325          * Deal with SIGIO first because the alarm handler might
0326          * schedule, leaving the pending SIGIO stranded until we come
0327          * back here.
0328          *
0329          * SIGIO's handler doesn't use siginfo or mcontext,
0330          * so they can be NULL.
0331          */
0332         if (save_pending & SIGIO_MASK)
0333             sig_handler_common(SIGIO, NULL, NULL);
0334 
0335         /* Do not reenter the handler */
0336 
0337         if ((save_pending & SIGALRM_MASK) && (!(signals_active & SIGALRM_MASK)))
0338             timer_real_alarm_handler(NULL);
0339 
0340         /* Rerun the loop only if there is still pending SIGIO and not in TIMER handler */
0341 
0342         if (!(signals_pending & SIGIO_MASK) && (signals_active & SIGALRM_MASK))
0343             return;
0344 
0345         /* Re-enable signals and trace that we're doing so. */
0346         um_trace_signals_on();
0347         signals_enabled = 1;
0348     }
0349 }
0350 
0351 int um_set_signals(int enable)
0352 {
0353     int ret;
0354     if (signals_enabled == enable)
0355         return enable;
0356 
0357     ret = signals_enabled;
0358     if (enable)
0359         unblock_signals();
0360     else block_signals();
0361 
0362     return ret;
0363 }
0364 
0365 int um_set_signals_trace(int enable)
0366 {
0367     int ret;
0368     if (signals_enabled == enable)
0369         return enable;
0370 
0371     ret = signals_enabled;
0372     if (enable)
0373         unblock_signals_trace();
0374     else
0375         block_signals_trace();
0376 
0377     return ret;
0378 }
0379 
0380 #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
0381 void mark_sigio_pending(void)
0382 {
0383     signals_pending |= SIGIO_MASK;
0384 }
0385 
0386 void block_signals_hard(void)
0387 {
0388     if (signals_blocked)
0389         return;
0390     signals_blocked = 1;
0391     barrier();
0392 }
0393 
0394 void unblock_signals_hard(void)
0395 {
0396     if (!signals_blocked)
0397         return;
0398     /* Must be set to 0 before we check the pending bits etc. */
0399     signals_blocked = 0;
0400     barrier();
0401 
0402     if (signals_pending && signals_enabled) {
0403         /* this is a bit inefficient, but that's not really important */
0404         block_signals();
0405         unblock_signals();
0406     } else if (signals_pending & SIGIO_MASK) {
0407         /* we need to run time-travel handlers even if not enabled */
0408         sigio_run_timetravel_handlers();
0409     }
0410 }
0411 #endif
0412 
0413 int os_is_signal_stack(void)
0414 {
0415     stack_t ss;
0416     sigaltstack(NULL, &ss);
0417 
0418     return ss.ss_flags & SS_ONSTACK;
0419 }