167276Sjon// SPDX-License-Identifier: GPL-2.0 267276Sjon/* 367276Sjon * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 467276Sjon */ 567276Sjon 667276Sjon#include <linux/module.h> 767276Sjon#include <linux/ptrace.h> 867276Sjon#include <linux/sched.h> 967276Sjon#include <linux/ftrace.h> 1067276Sjon#include <asm/siginfo.h> 1167276Sjon#include <asm/signal.h> 1267276Sjon#include <asm/unistd.h> 1367276Sjon#include <frame_kern.h> 1467276Sjon#include <kern_util.h> 1567276Sjon#include <os.h> 1667276Sjon 1767276SjonEXPORT_SYMBOL(block_signals); 1867276SjonEXPORT_SYMBOL(unblock_signals); 1967276Sjon 2067276Sjonvoid block_signals_trace(void) 2167276Sjon{ 2267276Sjon block_signals(); 2367276Sjon if (current_thread_info()) 2467276Sjon trace_hardirqs_off(); 2567276Sjon} 2667276Sjon 2767276Sjonvoid unblock_signals_trace(void) 2867276Sjon{ 2967276Sjon if (current_thread_info()) 3067276Sjon trace_hardirqs_on(); 3167276Sjon unblock_signals(); 3267276Sjon} 3367276Sjon 3467276Sjonvoid um_trace_signals_on(void) 3567276Sjon{ 3667276Sjon if (current_thread_info()) 3782375Sjon trace_hardirqs_on(); 3867276Sjon} 3967276Sjon 4067276Sjonvoid um_trace_signals_off(void) 4167276Sjon{ 4282378Sjon if (current_thread_info()) 4382378Sjon trace_hardirqs_off(); 4482375Sjon} 4582375Sjon 4682378Sjon/* 4782378Sjon * OK, we're invoking a handler 4882378Sjon */ 4982378Sjonstatic void handle_signal(struct ksignal *ksig, struct pt_regs *regs) 5082378Sjon{ 5167276Sjon sigset_t *oldset = sigmask_to_save(); 5267276Sjon int singlestep = 0; 5382375Sjon unsigned long sp; 5467276Sjon int err; 5567276Sjon 5690751Simp if (test_thread_flag(TIF_SINGLESTEP) && (current->ptrace & PT_PTRACED)) 5789949Simp singlestep = 1; 5890751Simp 5990751Simp /* Did we come from a system call? */ 6090751Simp if (PT_REGS_SYSCALL_NR(regs) >= 0) { 6190751Simp /* If so, check system call restarting.. */ 6290751Simp switch (PT_REGS_SYSCALL_RET(regs)) { 6390751Simp case -ERESTART_RESTARTBLOCK: 6490751Simp case -ERESTARTNOHAND: 6598156Simp PT_REGS_SYSCALL_RET(regs) = -EINTR; 6698156Simp break; 6790751Simp 6869288Sjon case -ERESTARTSYS: 6969288Sjon if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { 7069288Sjon PT_REGS_SYSCALL_RET(regs) = -EINTR; 7190751Simp break; 7267276Sjon } 7367276Sjon fallthrough; 74100704Simp case -ERESTARTNOINTR: 75100704Simp PT_REGS_RESTART_SYSCALL(regs); 76100704Simp PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); 77100704Simp break; 78100704Simp } 79100704Simp } 80100704Simp 8167276Sjon sp = PT_REGS_SP(regs); 8267276Sjon if ((ksig->ka.sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) 8390751Simp sp = current->sas_ss_sp + current->sas_ss_size; 8490751Simp 8567276Sjon#ifdef CONFIG_ARCH_HAS_SC_SIGNALS 8690751Simp if (!(ksig->ka.sa.sa_flags & SA_SIGINFO)) 8767276Sjon err = setup_signal_stack_sc(sp, ksig, regs, oldset); 8867276Sjon else 8969288Sjon#endif 9082375Sjon err = setup_signal_stack_si(sp, ksig, regs, oldset); 9182375Sjon 9282375Sjon signal_setup_done(err, ksig, singlestep); 9382375Sjon} 9482375Sjon 9569288Sjonvoid do_signal(struct pt_regs *regs) 9669288Sjon{ 9782375Sjon struct ksignal ksig; 9882375Sjon int handled_sig = 0; 9982375Sjon 10082375Sjon while (get_signal(&ksig)) { 10182375Sjon handled_sig = 1; 10282375Sjon /* Whee! Actually deliver the signal. */ 10382375Sjon handle_signal(&ksig, regs); 10482375Sjon } 10582375Sjon 10682375Sjon /* Did we come from a system call? */ 10782375Sjon if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) { 10882375Sjon /* Restart the system call - no handlers present */ 109 switch (PT_REGS_SYSCALL_RET(regs)) { 110 case -ERESTARTNOHAND: 111 case -ERESTARTSYS: 112 case -ERESTARTNOINTR: 113 PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); 114 PT_REGS_RESTART_SYSCALL(regs); 115 break; 116 case -ERESTART_RESTARTBLOCK: 117 PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; 118 PT_REGS_RESTART_SYSCALL(regs); 119 break; 120 } 121 } 122 123 /* 124 * if there's no signal to deliver, we just put the saved sigmask 125 * back 126 */ 127 if (!handled_sig) 128 restore_saved_sigmask(); 129} 130