xref: /linux/arch/csky/kernel/signal.c (revision 96d4f267e40f9509e8a66e2b39e8b95655617693)
1e9564df7SGuo Ren // SPDX-License-Identifier: GPL-2.0
2e9564df7SGuo Ren // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3e9564df7SGuo Ren 
4e9564df7SGuo Ren #include <linux/sched.h>
5e9564df7SGuo Ren #include <linux/mm.h>
6e9564df7SGuo Ren #include <linux/kernel.h>
7e9564df7SGuo Ren #include <linux/signal.h>
8e9564df7SGuo Ren #include <linux/syscalls.h>
9e9564df7SGuo Ren #include <linux/errno.h>
10e9564df7SGuo Ren #include <linux/wait.h>
11e9564df7SGuo Ren #include <linux/ptrace.h>
12e9564df7SGuo Ren #include <linux/unistd.h>
13e9564df7SGuo Ren #include <linux/stddef.h>
14e9564df7SGuo Ren #include <linux/highuid.h>
15e9564df7SGuo Ren #include <linux/personality.h>
16e9564df7SGuo Ren #include <linux/tty.h>
17e9564df7SGuo Ren #include <linux/binfmts.h>
18e9564df7SGuo Ren #include <linux/tracehook.h>
19e9564df7SGuo Ren #include <linux/freezer.h>
20e9564df7SGuo Ren #include <linux/uaccess.h>
21e9564df7SGuo Ren 
22e9564df7SGuo Ren #include <asm/setup.h>
23e9564df7SGuo Ren #include <asm/pgtable.h>
24e9564df7SGuo Ren #include <asm/traps.h>
25e9564df7SGuo Ren #include <asm/ucontext.h>
26e9564df7SGuo Ren #include <asm/vdso.h>
27e9564df7SGuo Ren 
28e9564df7SGuo Ren #include <abi/regdef.h>
29e9564df7SGuo Ren 
30e9564df7SGuo Ren #ifdef CONFIG_CPU_HAS_FPU
31e9564df7SGuo Ren #include <abi/fpu.h>
32e9564df7SGuo Ren 
33e9564df7SGuo Ren static int restore_fpu_state(struct sigcontext *sc)
34e9564df7SGuo Ren {
35e9564df7SGuo Ren 	int err = 0;
36e9564df7SGuo Ren 	struct user_fp user_fp;
37e9564df7SGuo Ren 
38e9564df7SGuo Ren 	err = copy_from_user(&user_fp, &sc->sc_user_fp, sizeof(user_fp));
39e9564df7SGuo Ren 
40e9564df7SGuo Ren 	restore_from_user_fp(&user_fp);
41e9564df7SGuo Ren 
42e9564df7SGuo Ren 	return err;
43e9564df7SGuo Ren }
44e9564df7SGuo Ren 
45e9564df7SGuo Ren static int save_fpu_state(struct sigcontext *sc)
46e9564df7SGuo Ren {
47e9564df7SGuo Ren 	struct user_fp user_fp;
48e9564df7SGuo Ren 
49e9564df7SGuo Ren 	save_to_user_fp(&user_fp);
50e9564df7SGuo Ren 
51e9564df7SGuo Ren 	return copy_to_user(&sc->sc_user_fp, &user_fp, sizeof(user_fp));
52e9564df7SGuo Ren }
53e9564df7SGuo Ren #else
54e9564df7SGuo Ren static inline int restore_fpu_state(struct sigcontext *sc) { return 0; }
55e9564df7SGuo Ren static inline int save_fpu_state(struct sigcontext *sc) { return 0; }
56e9564df7SGuo Ren #endif
57e9564df7SGuo Ren 
58e9564df7SGuo Ren struct rt_sigframe {
59e9564df7SGuo Ren 	int sig;
60e9564df7SGuo Ren 	struct siginfo *pinfo;
61e9564df7SGuo Ren 	void *puc;
62e9564df7SGuo Ren 	struct siginfo info;
63e9564df7SGuo Ren 	struct ucontext uc;
64e9564df7SGuo Ren };
65e9564df7SGuo Ren 
66e9564df7SGuo Ren static int
67e9564df7SGuo Ren restore_sigframe(struct pt_regs *regs,
68e9564df7SGuo Ren 		 struct sigcontext *sc, int *pr2)
69e9564df7SGuo Ren {
70e9564df7SGuo Ren 	int err = 0;
71e9564df7SGuo Ren 
72e9564df7SGuo Ren 	/* Always make any pending restarted system calls return -EINTR */
73e9564df7SGuo Ren 	current_thread_info()->task->restart_block.fn = do_no_restart_syscall;
74e9564df7SGuo Ren 
75e9564df7SGuo Ren 	err |= copy_from_user(regs, &sc->sc_pt_regs, sizeof(struct pt_regs));
76e9564df7SGuo Ren 
77e9564df7SGuo Ren 	err |= restore_fpu_state(sc);
78e9564df7SGuo Ren 
79e9564df7SGuo Ren 	*pr2 = regs->a0;
80e9564df7SGuo Ren 	return err;
81e9564df7SGuo Ren }
82e9564df7SGuo Ren 
83e9564df7SGuo Ren asmlinkage int
84e9564df7SGuo Ren do_rt_sigreturn(void)
85e9564df7SGuo Ren {
86e9564df7SGuo Ren 	sigset_t set;
87e9564df7SGuo Ren 	int a0;
88e9564df7SGuo Ren 	struct pt_regs *regs = current_pt_regs();
89e9564df7SGuo Ren 	struct rt_sigframe *frame = (struct rt_sigframe *)(regs->usp);
90e9564df7SGuo Ren 
91*96d4f267SLinus Torvalds 	if (!access_ok(frame, sizeof(*frame)))
92e9564df7SGuo Ren 		goto badframe;
93e9564df7SGuo Ren 	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
94e9564df7SGuo Ren 		goto badframe;
95e9564df7SGuo Ren 
96e9564df7SGuo Ren 	sigdelsetmask(&set, (sigmask(SIGKILL) | sigmask(SIGSTOP)));
97e9564df7SGuo Ren 	spin_lock_irq(&current->sighand->siglock);
98e9564df7SGuo Ren 	current->blocked = set;
99e9564df7SGuo Ren 	recalc_sigpending();
100e9564df7SGuo Ren 	spin_unlock_irq(&current->sighand->siglock);
101e9564df7SGuo Ren 
102e9564df7SGuo Ren 	if (restore_sigframe(regs, &frame->uc.uc_mcontext, &a0))
103e9564df7SGuo Ren 		goto badframe;
104e9564df7SGuo Ren 
105e9564df7SGuo Ren 	return a0;
106e9564df7SGuo Ren 
107e9564df7SGuo Ren badframe:
108e9564df7SGuo Ren 	force_sig(SIGSEGV, current);
109e9564df7SGuo Ren 	return 0;
110e9564df7SGuo Ren }
111e9564df7SGuo Ren 
112e9564df7SGuo Ren static int setup_sigframe(struct sigcontext *sc, struct pt_regs *regs)
113e9564df7SGuo Ren {
114e9564df7SGuo Ren 	int err = 0;
115e9564df7SGuo Ren 
116e9564df7SGuo Ren 	err |= copy_to_user(&sc->sc_pt_regs, regs, sizeof(struct pt_regs));
117e9564df7SGuo Ren 	err |= save_fpu_state(sc);
118e9564df7SGuo Ren 
119e9564df7SGuo Ren 	return err;
120e9564df7SGuo Ren }
121e9564df7SGuo Ren 
122e9564df7SGuo Ren static inline void *
123e9564df7SGuo Ren get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
124e9564df7SGuo Ren {
125e9564df7SGuo Ren 	unsigned long usp;
126e9564df7SGuo Ren 
127e9564df7SGuo Ren 	/* Default to using normal stack.  */
128e9564df7SGuo Ren 	usp = regs->usp;
129e9564df7SGuo Ren 
130e9564df7SGuo Ren 	/* This is the X/Open sanctioned signal stack switching.  */
131e9564df7SGuo Ren 	if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(usp)) {
132e9564df7SGuo Ren 		if (!on_sig_stack(usp))
133e9564df7SGuo Ren 			usp = current->sas_ss_sp + current->sas_ss_size;
134e9564df7SGuo Ren 	}
135e9564df7SGuo Ren 	return (void *)((usp - frame_size) & -8UL);
136e9564df7SGuo Ren }
137e9564df7SGuo Ren 
138e9564df7SGuo Ren static int
139e9564df7SGuo Ren setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
140e9564df7SGuo Ren {
141e9564df7SGuo Ren 	struct rt_sigframe *frame;
142e9564df7SGuo Ren 	int err = 0;
143e9564df7SGuo Ren 
144e9564df7SGuo Ren 	struct csky_vdso *vdso = current->mm->context.vdso;
145e9564df7SGuo Ren 
146e9564df7SGuo Ren 	frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
147e9564df7SGuo Ren 	if (!frame)
148e9564df7SGuo Ren 		return 1;
149e9564df7SGuo Ren 
150e9564df7SGuo Ren 	err |= __put_user(ksig->sig, &frame->sig);
151e9564df7SGuo Ren 	err |= __put_user(&frame->info, &frame->pinfo);
152e9564df7SGuo Ren 	err |= __put_user(&frame->uc, &frame->puc);
153e9564df7SGuo Ren 	err |= copy_siginfo_to_user(&frame->info, &ksig->info);
154e9564df7SGuo Ren 
155e9564df7SGuo Ren 	/* Create the ucontext.  */
156e9564df7SGuo Ren 	err |= __put_user(0, &frame->uc.uc_flags);
157e9564df7SGuo Ren 	err |= __put_user(0, &frame->uc.uc_link);
158e9564df7SGuo Ren 	err |= __put_user((void *)current->sas_ss_sp,
159e9564df7SGuo Ren 			&frame->uc.uc_stack.ss_sp);
160e9564df7SGuo Ren 	err |= __put_user(sas_ss_flags(regs->usp),
161e9564df7SGuo Ren 			&frame->uc.uc_stack.ss_flags);
162e9564df7SGuo Ren 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
163e9564df7SGuo Ren 	err |= setup_sigframe(&frame->uc.uc_mcontext, regs);
164e9564df7SGuo Ren 	err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
165e9564df7SGuo Ren 
166e9564df7SGuo Ren 	if (err)
167e9564df7SGuo Ren 		goto give_sigsegv;
168e9564df7SGuo Ren 
169e9564df7SGuo Ren 	/* Set up registers for signal handler */
170e9564df7SGuo Ren 	regs->usp = (unsigned long)frame;
171e9564df7SGuo Ren 	regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
172e9564df7SGuo Ren 	regs->lr = (unsigned long)vdso->rt_signal_retcode;
173e9564df7SGuo Ren 
174e9564df7SGuo Ren adjust_stack:
175e9564df7SGuo Ren 	regs->a0 = ksig->sig; /* first arg is signo */
176e9564df7SGuo Ren 	regs->a1 = (unsigned long)(&(frame->info));
177e9564df7SGuo Ren 	regs->a2 = (unsigned long)(&(frame->uc));
178e9564df7SGuo Ren 	return err;
179e9564df7SGuo Ren 
180e9564df7SGuo Ren give_sigsegv:
181e9564df7SGuo Ren 	if (ksig->sig == SIGSEGV)
182e9564df7SGuo Ren 		ksig->ka.sa.sa_handler = SIG_DFL;
183e9564df7SGuo Ren 	force_sig(SIGSEGV, current);
184e9564df7SGuo Ren 	goto adjust_stack;
185e9564df7SGuo Ren }
186e9564df7SGuo Ren 
187e9564df7SGuo Ren /*
188e9564df7SGuo Ren  * OK, we're invoking a handler
189e9564df7SGuo Ren  */
190e9564df7SGuo Ren static int
191e9564df7SGuo Ren handle_signal(struct ksignal *ksig, struct pt_regs *regs)
192e9564df7SGuo Ren {
193e9564df7SGuo Ren 	int ret;
194e9564df7SGuo Ren 	sigset_t *oldset = sigmask_to_save();
195e9564df7SGuo Ren 
196e9564df7SGuo Ren 	/*
197e9564df7SGuo Ren 	 * set up the stack frame, regardless of SA_SIGINFO,
198e9564df7SGuo Ren 	 * and pass info anyway.
199e9564df7SGuo Ren 	 */
200e9564df7SGuo Ren 	ret = setup_rt_frame(ksig, oldset, regs);
201e9564df7SGuo Ren 
202e9564df7SGuo Ren 	if (ret != 0) {
203e9564df7SGuo Ren 		force_sigsegv(ksig->sig, current);
204e9564df7SGuo Ren 		return ret;
205e9564df7SGuo Ren 	}
206e9564df7SGuo Ren 
207e9564df7SGuo Ren 	/* Block the signal if we were successful. */
208e9564df7SGuo Ren 	spin_lock_irq(&current->sighand->siglock);
209e9564df7SGuo Ren 	sigorsets(&current->blocked, &current->blocked, &ksig->ka.sa.sa_mask);
210e9564df7SGuo Ren 	if (!(ksig->ka.sa.sa_flags & SA_NODEFER))
211e9564df7SGuo Ren 		sigaddset(&current->blocked, ksig->sig);
212e9564df7SGuo Ren 	recalc_sigpending();
213e9564df7SGuo Ren 	spin_unlock_irq(&current->sighand->siglock);
214e9564df7SGuo Ren 
215e9564df7SGuo Ren 	return 0;
216e9564df7SGuo Ren }
217e9564df7SGuo Ren 
218e9564df7SGuo Ren /*
219e9564df7SGuo Ren  * Note that 'init' is a special process: it doesn't get signals it doesn't
220e9564df7SGuo Ren  * want to handle. Thus you cannot kill init even with a SIGKILL even by
221e9564df7SGuo Ren  * mistake.
222e9564df7SGuo Ren  *
223e9564df7SGuo Ren  * Note that we go through the signals twice: once to check the signals
224e9564df7SGuo Ren  * that the kernel can handle, and then we build all the user-level signal
225e9564df7SGuo Ren  * handling stack-frames in one go after that.
226e9564df7SGuo Ren  */
227e9564df7SGuo Ren static void do_signal(struct pt_regs *regs, int syscall)
228e9564df7SGuo Ren {
229e9564df7SGuo Ren 	unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
230e9564df7SGuo Ren 	struct ksignal ksig;
231e9564df7SGuo Ren 
232e9564df7SGuo Ren 	/*
233e9564df7SGuo Ren 	 * We want the common case to go fast, which
234e9564df7SGuo Ren 	 * is why we may in certain cases get here from
235e9564df7SGuo Ren 	 * kernel mode. Just return without doing anything
236e9564df7SGuo Ren 	 * if so.
237e9564df7SGuo Ren 	 */
238e9564df7SGuo Ren 	if (!user_mode(regs))
239e9564df7SGuo Ren 		return;
240e9564df7SGuo Ren 
241e9564df7SGuo Ren 	current->thread.esp0 = (unsigned long)regs;
242e9564df7SGuo Ren 
243e9564df7SGuo Ren 	/*
244e9564df7SGuo Ren 	 * If we were from a system call, check for system call restarting...
245e9564df7SGuo Ren 	 */
246e9564df7SGuo Ren 	if (syscall) {
247e9564df7SGuo Ren 		continue_addr = regs->pc;
248e9564df7SGuo Ren #if defined(__CSKYABIV2__)
249e9564df7SGuo Ren 		restart_addr = continue_addr - 4;
250e9564df7SGuo Ren #else
251e9564df7SGuo Ren 		restart_addr = continue_addr - 2;
252e9564df7SGuo Ren #endif
253e9564df7SGuo Ren 		retval = regs->a0;
254e9564df7SGuo Ren 
255e9564df7SGuo Ren 		/*
256e9564df7SGuo Ren 		 * Prepare for system call restart.  We do this here so that a
257e9564df7SGuo Ren 		 * debugger will see the already changed.
258e9564df7SGuo Ren 		 */
259e9564df7SGuo Ren 		switch (retval) {
260e9564df7SGuo Ren 		case -ERESTARTNOHAND:
261e9564df7SGuo Ren 		case -ERESTARTSYS:
262e9564df7SGuo Ren 		case -ERESTARTNOINTR:
263e9564df7SGuo Ren 			regs->a0 = regs->orig_a0;
264e9564df7SGuo Ren 			regs->pc = restart_addr;
265e9564df7SGuo Ren 			break;
266e9564df7SGuo Ren 		case -ERESTART_RESTARTBLOCK:
267e9564df7SGuo Ren 			regs->a0 = -EINTR;
268e9564df7SGuo Ren 			break;
269e9564df7SGuo Ren 		}
270e9564df7SGuo Ren 	}
271e9564df7SGuo Ren 
272e9564df7SGuo Ren 	if (try_to_freeze())
273e9564df7SGuo Ren 		goto no_signal;
274e9564df7SGuo Ren 
275e9564df7SGuo Ren 	/*
276e9564df7SGuo Ren 	 * Get the signal to deliver.  When running under ptrace, at this
277e9564df7SGuo Ren 	 * point the debugger may change all our registers ...
278e9564df7SGuo Ren 	 */
279e9564df7SGuo Ren 	if (get_signal(&ksig)) {
280e9564df7SGuo Ren 		/*
281e9564df7SGuo Ren 		 * Depending on the signal settings we may need to revert the
282e9564df7SGuo Ren 		 * decision to restart the system call.  But skip this if a
283e9564df7SGuo Ren 		 * debugger has chosen to restart at a different PC.
284e9564df7SGuo Ren 		 */
285e9564df7SGuo Ren 		if (regs->pc == restart_addr) {
286e9564df7SGuo Ren 			if (retval == -ERESTARTNOHAND ||
287e9564df7SGuo Ren 			    (retval == -ERESTARTSYS &&
288e9564df7SGuo Ren 			     !(ksig.ka.sa.sa_flags & SA_RESTART))) {
289e9564df7SGuo Ren 				regs->a0 = -EINTR;
290e9564df7SGuo Ren 				regs->pc = continue_addr;
291e9564df7SGuo Ren 			}
292e9564df7SGuo Ren 		}
293e9564df7SGuo Ren 
294e9564df7SGuo Ren 		/* Whee!  Actually deliver the signal.  */
295e9564df7SGuo Ren 		if (handle_signal(&ksig, regs) == 0) {
296e9564df7SGuo Ren 			/*
297e9564df7SGuo Ren 			 * A signal was successfully delivered; the saved
298e9564df7SGuo Ren 			 * sigmask will have been stored in the signal frame,
299e9564df7SGuo Ren 			 * and will be restored by sigreturn, so we can simply
300e9564df7SGuo Ren 			 * clear the TIF_RESTORE_SIGMASK flag.
301e9564df7SGuo Ren 			 */
302e9564df7SGuo Ren 			if (test_thread_flag(TIF_RESTORE_SIGMASK))
303e9564df7SGuo Ren 				clear_thread_flag(TIF_RESTORE_SIGMASK);
304e9564df7SGuo Ren 		}
305e9564df7SGuo Ren 		return;
306e9564df7SGuo Ren 	}
307e9564df7SGuo Ren 
308e9564df7SGuo Ren no_signal:
309e9564df7SGuo Ren 	if (syscall) {
310e9564df7SGuo Ren 		/*
311e9564df7SGuo Ren 		 * Handle restarting a different system call.  As above,
312e9564df7SGuo Ren 		 * if a debugger has chosen to restart at a different PC,
313e9564df7SGuo Ren 		 * ignore the restart.
314e9564df7SGuo Ren 		 */
315e9564df7SGuo Ren 		if (retval == -ERESTART_RESTARTBLOCK
316e9564df7SGuo Ren 				&& regs->pc == continue_addr) {
317e9564df7SGuo Ren #if defined(__CSKYABIV2__)
318e9564df7SGuo Ren 			regs->regs[3] = __NR_restart_syscall;
319e9564df7SGuo Ren 			regs->pc -= 4;
320e9564df7SGuo Ren #else
321e9564df7SGuo Ren 			regs->regs[9] = __NR_restart_syscall;
322e9564df7SGuo Ren 			regs->pc -= 2;
323e9564df7SGuo Ren #endif
324e9564df7SGuo Ren 		}
325e9564df7SGuo Ren 
326e9564df7SGuo Ren 		/*
327e9564df7SGuo Ren 		 * If there's no signal to deliver, we just put the saved
328e9564df7SGuo Ren 		 * sigmask back.
329e9564df7SGuo Ren 		 */
330e9564df7SGuo Ren 		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
331e9564df7SGuo Ren 			clear_thread_flag(TIF_RESTORE_SIGMASK);
332e9564df7SGuo Ren 			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
333e9564df7SGuo Ren 		}
334e9564df7SGuo Ren 	}
335e9564df7SGuo Ren }
336e9564df7SGuo Ren 
337e9564df7SGuo Ren asmlinkage void
338e9564df7SGuo Ren do_notify_resume(unsigned int thread_flags, struct pt_regs *regs, int syscall)
339e9564df7SGuo Ren {
340e9564df7SGuo Ren 	if (thread_flags & _TIF_SIGPENDING)
341e9564df7SGuo Ren 		do_signal(regs, syscall);
342e9564df7SGuo Ren 
343e9564df7SGuo Ren 	if (thread_flags & _TIF_NOTIFY_RESUME) {
344e9564df7SGuo Ren 		clear_thread_flag(TIF_NOTIFY_RESUME);
345e9564df7SGuo Ren 		tracehook_notify_resume(regs);
346e9564df7SGuo Ren 	}
347e9564df7SGuo Ren }
348