signal.c revision 1deb9c5dfb179819ecdbf80a1d121e26c63caab3
1867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 2867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Copyright (C) 1991, 1992 Linus Torvalds 3867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Copyright 2010 Tilera Corporation. All Rights Reserved. 4867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 5867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * This program is free software; you can redistribute it and/or 6867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * modify it under the terms of the GNU General Public License 7867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * as published by the Free Software Foundation, version 2. 8867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 9867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * This program is distributed in the hope that it will be useful, but 10867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * WITHOUT ANY WARRANTY; without even the implied warranty of 11867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 12867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * NON INFRINGEMENT. See the GNU General Public License for 13867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * more details. 14867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 15867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 16867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/sched.h> 17867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/mm.h> 18867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/smp.h> 19867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/smp_lock.h> 20867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/kernel.h> 21867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/signal.h> 22867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/errno.h> 23867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/wait.h> 24867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/unistd.h> 25867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/stddef.h> 26867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/personality.h> 27867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/suspend.h> 28867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/ptrace.h> 29867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/elf.h> 30867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/compat.h> 31867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/syscalls.h> 32867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/uaccess.h> 33867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <asm/processor.h> 34867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <asm/ucontext.h> 35867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <asm/sigframe.h> 360707ad30d10110aebc01a5a64fb63f4b32d20b73Chris Metcalf#include <asm/syscalls.h> 37867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <arch/interrupts.h> 38867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 39867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#define DEBUG_SIG 0 40867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 41867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 42867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 43867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 44d929b6aeaacbe78cbfef4a80e3eed1bf0464d984Chris MetcalfSYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss, 45d929b6aeaacbe78cbfef4a80e3eed1bf0464d984Chris Metcalf stack_t __user *, uoss, struct pt_regs *, regs) 46867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 47867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return do_sigaltstack(uss, uoss, regs->sp); 48867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 49867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 50867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 51867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 52867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Do a signal return; undo the signal stack. 53867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 54867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 55867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfint restore_sigcontext(struct pt_regs *regs, 56867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct sigcontext __user *sc, long *pr0) 57867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 58867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int err = 0; 59867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int i; 60867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 61867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Always make any pending restarted system calls return -EINTR */ 62867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf current_thread_info()->restart_block.fn = do_no_restart_syscall; 63867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 6474fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf /* 6574fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf * Enforce that sigcontext is like pt_regs, and doesn't mess 6674fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf * up our stack alignment rules. 6774fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf */ 6874fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs)); 6974fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0); 7074fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf 71867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) 7274fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf err |= __get_user(regs->regs[i], &sc->gregs[i]); 73867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 741deb9c5dfb179819ecdbf80a1d121e26c63caab3Chris Metcalf /* Ensure that the PL is always set to USER_PL. */ 751deb9c5dfb179819ecdbf80a1d121e26c63caab3Chris Metcalf regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1)); 761deb9c5dfb179819ecdbf80a1d121e26c63caab3Chris Metcalf 77867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->faultnum = INT_SWINT_1_SIGRETURN; 78867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 7974fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf err |= __get_user(*pr0, &sc->gregs[0]); 80867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return err; 81867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 82867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 830707ad30d10110aebc01a5a64fb63f4b32d20b73Chris Metcalf/* sigreturn() returns long since it restores r0 in the interrupted code. */ 84d929b6aeaacbe78cbfef4a80e3eed1bf0464d984Chris MetcalfSYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) 85867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 86867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct rt_sigframe __user *frame = 87867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf (struct rt_sigframe __user *)(regs->sp); 88867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigset_t set; 89867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf long r0; 90867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 91867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 92867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto badframe; 93867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 94867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto badframe; 95867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 96867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigdelsetmask(&set, ~_BLOCKABLE); 97867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf spin_lock_irq(¤t->sighand->siglock); 98867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf current->blocked = set; 99867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf recalc_sigpending(); 100867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf spin_unlock_irq(¤t->sighand->siglock); 101867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 102867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) 103867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto badframe; 104867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 105867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) 106867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto badframe; 107867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 108867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return r0; 109867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 110867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfbadframe: 111867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf force_sig(SIGSEGV, current); 112867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return 0; 113867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 114867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 115867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 116867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Set up a signal frame. 117867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 118867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 119867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfint setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) 120867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 121867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int i, err = 0; 122867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 123867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) 12474fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf err |= __put_user(regs->regs[i], &sc->gregs[i]); 125867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 126867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return err; 127867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 128867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 129867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 130867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Determine which stack to use.. 131867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 132867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic inline void __user *get_sigframe(struct k_sigaction *ka, 133867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct pt_regs *regs, 134867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf size_t frame_size) 135867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 136867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf unsigned long sp; 137867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 138867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Default to using normal stack */ 139867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sp = regs->sp; 140867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 141867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 142867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * If we are on the alternate signal stack and would overflow 143867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * it, don't. Return an always-bogus address instead so we 144867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * will die with SIGSEGV. 145867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 146867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) 1470707ad30d10110aebc01a5a64fb63f4b32d20b73Chris Metcalf return (void __user __force *)-1UL; 148867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 149867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* This is the X/Open sanctioned signal stack switching. */ 150867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (ka->sa.sa_flags & SA_ONSTACK) { 151867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (sas_ss_flags(sp) == 0) 152867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sp = current->sas_ss_sp + current->sas_ss_size; 153867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 154867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 155867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sp -= frame_size; 156867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 157867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Align the stack pointer according to the TILE ABI, 158867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * i.e. so that on function entry (sp & 15) == 0. 159867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 160867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sp &= -16UL; 161867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return (void __user *) sp; 162867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 163867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 164867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 165867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigset_t *set, struct pt_regs *regs) 166867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 167867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf unsigned long restorer; 168867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct rt_sigframe __user *frame; 169867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int err = 0; 170867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int usig; 171867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 172867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf frame = get_sigframe(ka, regs, sizeof(*frame)); 173867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 174867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 175867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto give_sigsegv; 176867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 177867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf usig = current_thread_info()->exec_domain 178867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf && current_thread_info()->exec_domain->signal_invmap 179867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf && sig < 32 180867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf ? current_thread_info()->exec_domain->signal_invmap[sig] 181867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf : sig; 182867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 183867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Always write at least the signal number for the stack backtracer. */ 184867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (ka->sa.sa_flags & SA_SIGINFO) { 185867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* At sigreturn time, restore the callee-save registers too. */ 186867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= copy_siginfo_to_user(&frame->info, info); 187867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->flags |= PT_FLAGS_RESTORE_REGS; 188867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } else { 189867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __put_user(info->si_signo, &frame->info.si_signo); 190867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 191867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 192867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Create the ucontext. */ 193867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __clear_user(&frame->save_area, sizeof(frame->save_area)); 194867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __put_user(0, &frame->uc.uc_flags); 1950707ad30d10110aebc01a5a64fb63f4b32d20b73Chris Metcalf err |= __put_user(NULL, &frame->uc.uc_link); 1960707ad30d10110aebc01a5a64fb63f4b32d20b73Chris Metcalf err |= __put_user((void __user *)(current->sas_ss_sp), 197867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf &frame->uc.uc_stack.ss_sp); 198867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __put_user(sas_ss_flags(regs->sp), 199867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf &frame->uc.uc_stack.ss_flags); 200867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 201867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); 202867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 203867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (err) 204867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf goto give_sigsegv; 205867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 206867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf restorer = VDSO_BASE; 207867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (ka->sa.sa_flags & SA_RESTORER) 208867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf restorer = (unsigned long) ka->sa.sa_restorer; 209867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 210867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 211867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Set up registers for signal handler. 212867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Registers that we don't modify keep the value they had from 213867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * user-space at the time we took the signal. 21474fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf * We always pass siginfo and mcontext, regardless of SA_SIGINFO, 21574fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf * since some things rely on this (e.g. glibc's debug/segfault.c). 216867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 217867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->pc = (unsigned long) ka->sa.sa_handler; 218867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */ 219867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->sp = (unsigned long) frame; 220867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->lr = restorer; 221867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[0] = (unsigned long) usig; 22274fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf regs->regs[1] = (unsigned long) &frame->info; 22374fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf regs->regs[2] = (unsigned long) &frame->uc; 22474fca9da097b74117ae2cef9e5f0d9b0e28ccbb7Chris Metcalf regs->flags |= PT_FLAGS_CALLER_SAVES; 225867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 226867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 227867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Notify any tracer that was single-stepping it. 228867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * The tracer may want to single-step inside the 229867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * handler too. 230867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 231867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (test_thread_flag(TIF_SINGLESTEP)) 232867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf ptrace_notify(SIGTRAP); 233867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 234867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return 0; 235867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 236867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfgive_sigsegv: 237867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf force_sigsegv(sig, current); 238867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return -EFAULT; 239867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 240867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 241867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 242867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * OK, we're invoking a handler 243867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 244867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 245867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic int handle_signal(unsigned long sig, siginfo_t *info, 246867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct k_sigaction *ka, sigset_t *oldset, 247867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct pt_regs *regs) 248867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 249867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int ret; 250867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 251867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 252867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Are we from a system call? */ 253867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (regs->faultnum == INT_SWINT_1) { 254867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* If so, check system call restarting.. */ 255867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf switch (regs->regs[0]) { 256867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTART_RESTARTBLOCK: 257867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTNOHAND: 258867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[0] = -EINTR; 259867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf break; 260867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 261867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTSYS: 262867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (!(ka->sa.sa_flags & SA_RESTART)) { 263867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[0] = -EINTR; 264867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf break; 265867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 266867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* fallthrough */ 267867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTNOINTR: 268867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Reload caller-saves to restore r0..r5 and r10. */ 269867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->flags |= PT_FLAGS_CALLER_SAVES; 270867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[0] = regs->orig_r0; 271867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->pc -= 8; 272867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 273867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 274867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 275867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Set up the stack frame */ 276867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#ifdef CONFIG_COMPAT 277867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (is_compat_task()) 278867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf ret = compat_setup_rt_frame(sig, ka, info, oldset, regs); 279867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf else 280867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#endif 281867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf ret = setup_rt_frame(sig, ka, info, oldset, regs); 282867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (ret == 0) { 283867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* This code is only called from system calls or from 284867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * the work_pending path in the return-to-user code, and 285867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * either way we can re-enable interrupts unconditionally. 286867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 287867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf spin_lock_irq(¤t->sighand->siglock); 288867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigorsets(¤t->blocked, 289867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf ¤t->blocked, &ka->sa.sa_mask); 290867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (!(ka->sa.sa_flags & SA_NODEFER)) 291867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigaddset(¤t->blocked, sig); 292867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf recalc_sigpending(); 293867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf spin_unlock_irq(¤t->sighand->siglock); 294867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 295867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 296867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return ret; 297867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 298867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 299867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 300867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Note that 'init' is a special process: it doesn't get signals it doesn't 301867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * want to handle. Thus you cannot kill init even with a SIGKILL even by 302867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * mistake. 303867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 304867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfvoid do_signal(struct pt_regs *regs) 305867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 306867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf siginfo_t info; 307867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf int signr; 308867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf struct k_sigaction ka; 309867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigset_t *oldset; 310867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 311867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 312867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * i386 will check if we're coming from kernel mode and bail out 313867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * here. In my experience this just turns weird crashes into 314867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * weird spin-hangs. But if we find a case where this seems 315867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * helpful, we can reinstate the check on "!user_mode(regs)". 316867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 317867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 318867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (current_thread_info()->status & TS_RESTORE_SIGMASK) 319867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf oldset = ¤t->saved_sigmask; 320867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf else 321867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf oldset = ¤t->blocked; 322867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 323867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf signr = get_signal_to_deliver(&info, &ka, regs, NULL); 324867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (signr > 0) { 325867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Whee! Actually deliver the signal. */ 326867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { 327867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* 328867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * A signal was successfully delivered; the saved 329867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * sigmask will have been stored in the signal frame, 330867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * and will be restored by sigreturn, so we can simply 331867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * clear the TS_RESTORE_SIGMASK flag. 332867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 333867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 334867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 335867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 33634a89d26bdc4ba46a406fa3842239e921c493d44Chris Metcalf goto done; 337867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 338867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 339867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Did we come from a system call? */ 340867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (regs->faultnum == INT_SWINT_1) { 341867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* Restart the system call - no handlers present */ 342867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf switch (regs->regs[0]) { 343867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTNOHAND: 344867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTSYS: 345867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTARTNOINTR: 346867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->flags |= PT_FLAGS_CALLER_SAVES; 347867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[0] = regs->orig_r0; 348867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->pc -= 8; 349867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf break; 350867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 351867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf case -ERESTART_RESTARTBLOCK: 352867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->flags |= PT_FLAGS_CALLER_SAVES; 353867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->regs[TREG_SYSCALL_NR] = __NR_restart_syscall; 354867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf regs->pc -= 8; 355867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf break; 356867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 357867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 358867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 359867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf /* If there's no signal to deliver, just put the saved sigmask back. */ 360867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf if (current_thread_info()->status & TS_RESTORE_SIGMASK) { 361867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 362867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); 363867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf } 36434a89d26bdc4ba46a406fa3842239e921c493d44Chris Metcalf 36534a89d26bdc4ba46a406fa3842239e921c493d44Chris Metcalfdone: 36634a89d26bdc4ba46a406fa3842239e921c493d44Chris Metcalf /* Avoid double syscall restart if there are nested signals. */ 36734a89d26bdc4ba46a406fa3842239e921c493d44Chris Metcalf regs->faultnum = INT_SWINT_1_SIGRETURN; 368867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 369