162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk}) 462306a36Sopenharmony_ci * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de) 562306a36Sopenharmony_ci * Copyright (C) 2004 PathScale, Inc 662306a36Sopenharmony_ci * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <stdlib.h> 1062306a36Sopenharmony_ci#include <stdarg.h> 1162306a36Sopenharmony_ci#include <errno.h> 1262306a36Sopenharmony_ci#include <signal.h> 1362306a36Sopenharmony_ci#include <string.h> 1462306a36Sopenharmony_ci#include <strings.h> 1562306a36Sopenharmony_ci#include <as-layout.h> 1662306a36Sopenharmony_ci#include <kern_util.h> 1762306a36Sopenharmony_ci#include <os.h> 1862306a36Sopenharmony_ci#include <sysdep/mcontext.h> 1962306a36Sopenharmony_ci#include <um_malloc.h> 2062306a36Sopenharmony_ci#include <sys/ucontext.h> 2162306a36Sopenharmony_ci#include <timetravel.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_civoid (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = { 2462306a36Sopenharmony_ci [SIGTRAP] = relay_signal, 2562306a36Sopenharmony_ci [SIGFPE] = relay_signal, 2662306a36Sopenharmony_ci [SIGILL] = relay_signal, 2762306a36Sopenharmony_ci [SIGWINCH] = winch, 2862306a36Sopenharmony_ci [SIGBUS] = bus_handler, 2962306a36Sopenharmony_ci [SIGSEGV] = segv_handler, 3062306a36Sopenharmony_ci [SIGIO] = sigio_handler, 3162306a36Sopenharmony_ci}; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistatic void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc) 3462306a36Sopenharmony_ci{ 3562306a36Sopenharmony_ci struct uml_pt_regs r; 3662306a36Sopenharmony_ci int save_errno = errno; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci r.is_user = 0; 3962306a36Sopenharmony_ci if (sig == SIGSEGV) { 4062306a36Sopenharmony_ci /* For segfaults, we want the data from the sigcontext. */ 4162306a36Sopenharmony_ci get_regs_from_mc(&r, mc); 4262306a36Sopenharmony_ci GET_FAULTINFO_FROM_MC(r.faultinfo, mc); 4362306a36Sopenharmony_ci } 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci /* enable signals if sig isn't IRQ signal */ 4662306a36Sopenharmony_ci if ((sig != SIGIO) && (sig != SIGWINCH)) 4762306a36Sopenharmony_ci unblock_signals_trace(); 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci (*sig_info[sig])(sig, si, &r); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci errno = save_errno; 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci/* 5562306a36Sopenharmony_ci * These are the asynchronous signals. SIGPROF is excluded because we want to 5662306a36Sopenharmony_ci * be able to profile all of UML, not just the non-critical sections. If 5762306a36Sopenharmony_ci * profiling is not thread-safe, then that is not my problem. We can disable 5862306a36Sopenharmony_ci * profiling when SMP is enabled in that case. 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_ci#define SIGIO_BIT 0 6162306a36Sopenharmony_ci#define SIGIO_MASK (1 << SIGIO_BIT) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#define SIGALRM_BIT 1 6462306a36Sopenharmony_ci#define SIGALRM_MASK (1 << SIGALRM_BIT) 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ciint signals_enabled; 6762306a36Sopenharmony_ci#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT 6862306a36Sopenharmony_cistatic int signals_blocked; 6962306a36Sopenharmony_ci#else 7062306a36Sopenharmony_ci#define signals_blocked 0 7162306a36Sopenharmony_ci#endif 7262306a36Sopenharmony_cistatic unsigned int signals_pending; 7362306a36Sopenharmony_cistatic unsigned int signals_active = 0; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_civoid sig_handler(int sig, struct siginfo *si, mcontext_t *mc) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci int enabled = signals_enabled; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci if ((signals_blocked || !enabled) && (sig == SIGIO)) { 8062306a36Sopenharmony_ci /* 8162306a36Sopenharmony_ci * In TT_MODE_EXTERNAL, need to still call time-travel 8262306a36Sopenharmony_ci * handlers unless signals are also blocked for the 8362306a36Sopenharmony_ci * external time message processing. This will mark 8462306a36Sopenharmony_ci * signals_pending by itself (only if necessary.) 8562306a36Sopenharmony_ci */ 8662306a36Sopenharmony_ci if (!signals_blocked && time_travel_mode == TT_MODE_EXTERNAL) 8762306a36Sopenharmony_ci sigio_run_timetravel_handlers(); 8862306a36Sopenharmony_ci else 8962306a36Sopenharmony_ci signals_pending |= SIGIO_MASK; 9062306a36Sopenharmony_ci return; 9162306a36Sopenharmony_ci } 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci block_signals_trace(); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci sig_handler_common(sig, si, mc); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci um_set_signals_trace(enabled); 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic void timer_real_alarm_handler(mcontext_t *mc) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci struct uml_pt_regs regs; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci if (mc != NULL) 10562306a36Sopenharmony_ci get_regs_from_mc(®s, mc); 10662306a36Sopenharmony_ci else 10762306a36Sopenharmony_ci memset(®s, 0, sizeof(regs)); 10862306a36Sopenharmony_ci timer_handler(SIGALRM, NULL, ®s); 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_civoid timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci int enabled; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci enabled = signals_enabled; 11662306a36Sopenharmony_ci if (!signals_enabled) { 11762306a36Sopenharmony_ci signals_pending |= SIGALRM_MASK; 11862306a36Sopenharmony_ci return; 11962306a36Sopenharmony_ci } 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci block_signals_trace(); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci signals_active |= SIGALRM_MASK; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci timer_real_alarm_handler(mc); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci signals_active &= ~SIGALRM_MASK; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci um_set_signals_trace(enabled); 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_civoid deliver_alarm(void) { 13362306a36Sopenharmony_ci timer_alarm_handler(SIGALRM, NULL, NULL); 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_civoid timer_set_signal_handler(void) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci set_handler(SIGALRM); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_civoid set_sigstack(void *sig_stack, int size) 14262306a36Sopenharmony_ci{ 14362306a36Sopenharmony_ci stack_t stack = { 14462306a36Sopenharmony_ci .ss_flags = 0, 14562306a36Sopenharmony_ci .ss_sp = sig_stack, 14662306a36Sopenharmony_ci .ss_size = size 14762306a36Sopenharmony_ci }; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci if (sigaltstack(&stack, NULL) != 0) 15062306a36Sopenharmony_ci panic("enabling signal stack failed, errno = %d\n", errno); 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistatic void sigusr1_handler(int sig, struct siginfo *unused_si, mcontext_t *mc) 15462306a36Sopenharmony_ci{ 15562306a36Sopenharmony_ci uml_pm_wake(); 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_civoid register_pm_wake_signal(void) 15962306a36Sopenharmony_ci{ 16062306a36Sopenharmony_ci set_handler(SIGUSR1); 16162306a36Sopenharmony_ci} 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistatic void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = { 16462306a36Sopenharmony_ci [SIGSEGV] = sig_handler, 16562306a36Sopenharmony_ci [SIGBUS] = sig_handler, 16662306a36Sopenharmony_ci [SIGILL] = sig_handler, 16762306a36Sopenharmony_ci [SIGFPE] = sig_handler, 16862306a36Sopenharmony_ci [SIGTRAP] = sig_handler, 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci [SIGIO] = sig_handler, 17162306a36Sopenharmony_ci [SIGWINCH] = sig_handler, 17262306a36Sopenharmony_ci [SIGALRM] = timer_alarm_handler, 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci [SIGUSR1] = sigusr1_handler, 17562306a36Sopenharmony_ci}; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistatic void hard_handler(int sig, siginfo_t *si, void *p) 17862306a36Sopenharmony_ci{ 17962306a36Sopenharmony_ci ucontext_t *uc = p; 18062306a36Sopenharmony_ci mcontext_t *mc = &uc->uc_mcontext; 18162306a36Sopenharmony_ci unsigned long pending = 1UL << sig; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci do { 18462306a36Sopenharmony_ci int nested, bail; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci /* 18762306a36Sopenharmony_ci * pending comes back with one bit set for each 18862306a36Sopenharmony_ci * interrupt that arrived while setting up the stack, 18962306a36Sopenharmony_ci * plus a bit for this interrupt, plus the zero bit is 19062306a36Sopenharmony_ci * set if this is a nested interrupt. 19162306a36Sopenharmony_ci * If bail is true, then we interrupted another 19262306a36Sopenharmony_ci * handler setting up the stack. In this case, we 19362306a36Sopenharmony_ci * have to return, and the upper handler will deal 19462306a36Sopenharmony_ci * with this interrupt. 19562306a36Sopenharmony_ci */ 19662306a36Sopenharmony_ci bail = to_irq_stack(&pending); 19762306a36Sopenharmony_ci if (bail) 19862306a36Sopenharmony_ci return; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci nested = pending & 1; 20162306a36Sopenharmony_ci pending &= ~1; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci while ((sig = ffs(pending)) != 0){ 20462306a36Sopenharmony_ci sig--; 20562306a36Sopenharmony_ci pending &= ~(1 << sig); 20662306a36Sopenharmony_ci (*handlers[sig])(sig, (struct siginfo *)si, mc); 20762306a36Sopenharmony_ci } 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci /* 21062306a36Sopenharmony_ci * Again, pending comes back with a mask of signals 21162306a36Sopenharmony_ci * that arrived while tearing down the stack. If this 21262306a36Sopenharmony_ci * is non-zero, we just go back, set up the stack 21362306a36Sopenharmony_ci * again, and handle the new interrupts. 21462306a36Sopenharmony_ci */ 21562306a36Sopenharmony_ci if (!nested) 21662306a36Sopenharmony_ci pending = from_irq_stack(nested); 21762306a36Sopenharmony_ci } while (pending); 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_civoid set_handler(int sig) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci struct sigaction action; 22362306a36Sopenharmony_ci int flags = SA_SIGINFO | SA_ONSTACK; 22462306a36Sopenharmony_ci sigset_t sig_mask; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci action.sa_sigaction = hard_handler; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci /* block irq ones */ 22962306a36Sopenharmony_ci sigemptyset(&action.sa_mask); 23062306a36Sopenharmony_ci sigaddset(&action.sa_mask, SIGIO); 23162306a36Sopenharmony_ci sigaddset(&action.sa_mask, SIGWINCH); 23262306a36Sopenharmony_ci sigaddset(&action.sa_mask, SIGALRM); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci if (sig == SIGSEGV) 23562306a36Sopenharmony_ci flags |= SA_NODEFER; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci if (sigismember(&action.sa_mask, sig)) 23862306a36Sopenharmony_ci flags |= SA_RESTART; /* if it's an irq signal */ 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci action.sa_flags = flags; 24162306a36Sopenharmony_ci action.sa_restorer = NULL; 24262306a36Sopenharmony_ci if (sigaction(sig, &action, NULL) < 0) 24362306a36Sopenharmony_ci panic("sigaction failed - errno = %d\n", errno); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci sigemptyset(&sig_mask); 24662306a36Sopenharmony_ci sigaddset(&sig_mask, sig); 24762306a36Sopenharmony_ci if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0) 24862306a36Sopenharmony_ci panic("sigprocmask failed - errno = %d\n", errno); 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_civoid send_sigio_to_self(void) 25262306a36Sopenharmony_ci{ 25362306a36Sopenharmony_ci kill(os_getpid(), SIGIO); 25462306a36Sopenharmony_ci} 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ciint change_sig(int signal, int on) 25762306a36Sopenharmony_ci{ 25862306a36Sopenharmony_ci sigset_t sigset; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci sigemptyset(&sigset); 26162306a36Sopenharmony_ci sigaddset(&sigset, signal); 26262306a36Sopenharmony_ci if (sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, NULL) < 0) 26362306a36Sopenharmony_ci return -errno; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci return 0; 26662306a36Sopenharmony_ci} 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_civoid block_signals(void) 26962306a36Sopenharmony_ci{ 27062306a36Sopenharmony_ci signals_enabled = 0; 27162306a36Sopenharmony_ci /* 27262306a36Sopenharmony_ci * This must return with signals disabled, so this barrier 27362306a36Sopenharmony_ci * ensures that writes are flushed out before the return. 27462306a36Sopenharmony_ci * This might matter if gcc figures out how to inline this and 27562306a36Sopenharmony_ci * decides to shuffle this code into the caller. 27662306a36Sopenharmony_ci */ 27762306a36Sopenharmony_ci barrier(); 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_civoid unblock_signals(void) 28162306a36Sopenharmony_ci{ 28262306a36Sopenharmony_ci int save_pending; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci if (signals_enabled == 1) 28562306a36Sopenharmony_ci return; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci signals_enabled = 1; 28862306a36Sopenharmony_ci#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT 28962306a36Sopenharmony_ci deliver_time_travel_irqs(); 29062306a36Sopenharmony_ci#endif 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci /* 29362306a36Sopenharmony_ci * We loop because the IRQ handler returns with interrupts off. So, 29462306a36Sopenharmony_ci * interrupts may have arrived and we need to re-enable them and 29562306a36Sopenharmony_ci * recheck signals_pending. 29662306a36Sopenharmony_ci */ 29762306a36Sopenharmony_ci while (1) { 29862306a36Sopenharmony_ci /* 29962306a36Sopenharmony_ci * Save and reset save_pending after enabling signals. This 30062306a36Sopenharmony_ci * way, signals_pending won't be changed while we're reading it. 30162306a36Sopenharmony_ci * 30262306a36Sopenharmony_ci * Setting signals_enabled and reading signals_pending must 30362306a36Sopenharmony_ci * happen in this order, so have the barrier here. 30462306a36Sopenharmony_ci */ 30562306a36Sopenharmony_ci barrier(); 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci save_pending = signals_pending; 30862306a36Sopenharmony_ci if (save_pending == 0) 30962306a36Sopenharmony_ci return; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci signals_pending = 0; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci /* 31462306a36Sopenharmony_ci * We have pending interrupts, so disable signals, as the 31562306a36Sopenharmony_ci * handlers expect them off when they are called. They will 31662306a36Sopenharmony_ci * be enabled again above. We need to trace this, as we're 31762306a36Sopenharmony_ci * expected to be enabling interrupts already, but any more 31862306a36Sopenharmony_ci * tracing that happens inside the handlers we call for the 31962306a36Sopenharmony_ci * pending signals will mess up the tracing state. 32062306a36Sopenharmony_ci */ 32162306a36Sopenharmony_ci signals_enabled = 0; 32262306a36Sopenharmony_ci um_trace_signals_off(); 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci /* 32562306a36Sopenharmony_ci * Deal with SIGIO first because the alarm handler might 32662306a36Sopenharmony_ci * schedule, leaving the pending SIGIO stranded until we come 32762306a36Sopenharmony_ci * back here. 32862306a36Sopenharmony_ci * 32962306a36Sopenharmony_ci * SIGIO's handler doesn't use siginfo or mcontext, 33062306a36Sopenharmony_ci * so they can be NULL. 33162306a36Sopenharmony_ci */ 33262306a36Sopenharmony_ci if (save_pending & SIGIO_MASK) 33362306a36Sopenharmony_ci sig_handler_common(SIGIO, NULL, NULL); 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci /* Do not reenter the handler */ 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci if ((save_pending & SIGALRM_MASK) && (!(signals_active & SIGALRM_MASK))) 33862306a36Sopenharmony_ci timer_real_alarm_handler(NULL); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci /* Rerun the loop only if there is still pending SIGIO and not in TIMER handler */ 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci if (!(signals_pending & SIGIO_MASK) && (signals_active & SIGALRM_MASK)) 34362306a36Sopenharmony_ci return; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci /* Re-enable signals and trace that we're doing so. */ 34662306a36Sopenharmony_ci um_trace_signals_on(); 34762306a36Sopenharmony_ci signals_enabled = 1; 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci} 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ciint um_set_signals(int enable) 35262306a36Sopenharmony_ci{ 35362306a36Sopenharmony_ci int ret; 35462306a36Sopenharmony_ci if (signals_enabled == enable) 35562306a36Sopenharmony_ci return enable; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci ret = signals_enabled; 35862306a36Sopenharmony_ci if (enable) 35962306a36Sopenharmony_ci unblock_signals(); 36062306a36Sopenharmony_ci else block_signals(); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci return ret; 36362306a36Sopenharmony_ci} 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ciint um_set_signals_trace(int enable) 36662306a36Sopenharmony_ci{ 36762306a36Sopenharmony_ci int ret; 36862306a36Sopenharmony_ci if (signals_enabled == enable) 36962306a36Sopenharmony_ci return enable; 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci ret = signals_enabled; 37262306a36Sopenharmony_ci if (enable) 37362306a36Sopenharmony_ci unblock_signals_trace(); 37462306a36Sopenharmony_ci else 37562306a36Sopenharmony_ci block_signals_trace(); 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci return ret; 37862306a36Sopenharmony_ci} 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT 38162306a36Sopenharmony_civoid mark_sigio_pending(void) 38262306a36Sopenharmony_ci{ 38362306a36Sopenharmony_ci signals_pending |= SIGIO_MASK; 38462306a36Sopenharmony_ci} 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_civoid block_signals_hard(void) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci if (signals_blocked) 38962306a36Sopenharmony_ci return; 39062306a36Sopenharmony_ci signals_blocked = 1; 39162306a36Sopenharmony_ci barrier(); 39262306a36Sopenharmony_ci} 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_civoid unblock_signals_hard(void) 39562306a36Sopenharmony_ci{ 39662306a36Sopenharmony_ci if (!signals_blocked) 39762306a36Sopenharmony_ci return; 39862306a36Sopenharmony_ci /* Must be set to 0 before we check the pending bits etc. */ 39962306a36Sopenharmony_ci signals_blocked = 0; 40062306a36Sopenharmony_ci barrier(); 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci if (signals_pending && signals_enabled) { 40362306a36Sopenharmony_ci /* this is a bit inefficient, but that's not really important */ 40462306a36Sopenharmony_ci block_signals(); 40562306a36Sopenharmony_ci unblock_signals(); 40662306a36Sopenharmony_ci } else if (signals_pending & SIGIO_MASK) { 40762306a36Sopenharmony_ci /* we need to run time-travel handlers even if not enabled */ 40862306a36Sopenharmony_ci sigio_run_timetravel_handlers(); 40962306a36Sopenharmony_ci } 41062306a36Sopenharmony_ci} 41162306a36Sopenharmony_ci#endif 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ciint os_is_signal_stack(void) 41462306a36Sopenharmony_ci{ 41562306a36Sopenharmony_ci stack_t ss; 41662306a36Sopenharmony_ci sigaltstack(NULL, &ss); 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci return ss.ss_flags & SS_ONSTACK; 41962306a36Sopenharmony_ci} 420