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(&current->sighand->siglock);
98867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf	current->blocked = set;
99867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf	recalc_sigpending();
100867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf	spin_unlock_irq(&current->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(&current->sighand->siglock);
288867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf		sigorsets(&current->blocked,
289867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf			  &current->blocked, &ka->sa.sa_mask);
290867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf		if (!(ka->sa.sa_flags & SA_NODEFER))
291867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf			sigaddset(&current->blocked, sig);
292867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf		recalc_sigpending();
293867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf		spin_unlock_irq(&current->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 = &current->saved_sigmask;
320867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf	else
321867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf		oldset = &current->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, &current->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