1 /*
2  * arch/score/kernel/signal.c
3  *
4  * Score Processor version.
5  *
6  * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7  *  Chen Liqin <liqin.chen@sunplusct.com>
8  *  Lennox Wu <lennox.wu@sunplusct.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, see the file COPYING, or write
22  * to the Free Software Foundation, Inc.,
23  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24  */
25 
26 #include <linux/errno.h>
27 #include <linux/signal.h>
28 #include <linux/ptrace.h>
29 #include <linux/unistd.h>
30 #include <linux/uaccess.h>
31 
32 #include <asm/cacheflush.h>
33 #include <asm/syscalls.h>
34 #include <asm/ucontext.h>
35 
36 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
37 
38 struct rt_sigframe {
39 	u32 rs_ass[4];		/* argument save space */
40 	u32 rs_code[2];		/* signal trampoline */
41 	struct siginfo rs_info;
42 	struct ucontext rs_uc;
43 };
44 
setup_sigcontext(struct pt_regs * regs,struct sigcontext __user * sc)45 static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
46 {
47 	int err = 0;
48 	unsigned long reg;
49 
50 	reg = regs->cp0_epc; err |= __put_user(reg, &sc->sc_pc);
51 	err |= __put_user(regs->cp0_psr, &sc->sc_psr);
52 	err |= __put_user(regs->cp0_condition, &sc->sc_condition);
53 
54 
55 #define save_gp_reg(i) {				\
56 	reg = regs->regs[i];				\
57 	err |= __put_user(reg, &sc->sc_regs[i]);	\
58 } while (0)
59 	save_gp_reg(0); save_gp_reg(1); save_gp_reg(2);
60 	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5);
61 	save_gp_reg(6);	save_gp_reg(7); save_gp_reg(8);
62 	save_gp_reg(9); save_gp_reg(10); save_gp_reg(11);
63 	save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
64 	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17);
65 	save_gp_reg(18); save_gp_reg(19); save_gp_reg(20);
66 	save_gp_reg(21); save_gp_reg(22); save_gp_reg(23);
67 	save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
68 	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29);
69 #undef save_gp_reg
70 
71 	reg = regs->ceh; err |= __put_user(reg, &sc->sc_mdceh);
72 	reg = regs->cel; err |= __put_user(reg, &sc->sc_mdcel);
73 	err |= __put_user(regs->cp0_ecr, &sc->sc_ecr);
74 	err |= __put_user(regs->cp0_ema, &sc->sc_ema);
75 
76 	return err;
77 }
78 
restore_sigcontext(struct pt_regs * regs,struct sigcontext __user * sc)79 static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
80 {
81 	int err = 0;
82 	u32 reg;
83 
84 	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
85 	err |= __get_user(regs->cp0_condition, &sc->sc_condition);
86 
87 	err |= __get_user(reg, &sc->sc_mdceh);
88 	regs->ceh = (int) reg;
89 	err |= __get_user(reg, &sc->sc_mdcel);
90 	regs->cel = (int) reg;
91 
92 	err |= __get_user(reg, &sc->sc_psr);
93 	regs->cp0_psr = (int) reg;
94 	err |= __get_user(reg, &sc->sc_ecr);
95 	regs->cp0_ecr = (int) reg;
96 	err |= __get_user(reg, &sc->sc_ema);
97 	regs->cp0_ema = (int) reg;
98 
99 #define restore_gp_reg(i) do {				\
100 	err |= __get_user(reg, &sc->sc_regs[i]);	\
101 	regs->regs[i] = reg;				\
102 } while (0)
103 	restore_gp_reg(0); restore_gp_reg(1); restore_gp_reg(2);
104 	restore_gp_reg(3); restore_gp_reg(4); restore_gp_reg(5);
105 	restore_gp_reg(6); restore_gp_reg(7); restore_gp_reg(8);
106 	restore_gp_reg(9); restore_gp_reg(10); restore_gp_reg(11);
107 	restore_gp_reg(12); restore_gp_reg(13); restore_gp_reg(14);
108 	restore_gp_reg(15); restore_gp_reg(16); restore_gp_reg(17);
109 	restore_gp_reg(18); restore_gp_reg(19);	restore_gp_reg(20);
110 	restore_gp_reg(21); restore_gp_reg(22); restore_gp_reg(23);
111 	restore_gp_reg(24); restore_gp_reg(25); restore_gp_reg(26);
112 	restore_gp_reg(27); restore_gp_reg(28); restore_gp_reg(29);
113 #undef restore_gp_reg
114 
115 	return err;
116 }
117 
118 /*
119  * Determine which stack to use..
120  */
get_sigframe(struct k_sigaction * ka,struct pt_regs * regs,size_t frame_size)121 static void __user *get_sigframe(struct k_sigaction *ka,
122 			struct pt_regs *regs, size_t frame_size)
123 {
124 	unsigned long sp;
125 
126 	/* Default to using normal stack */
127 	sp = regs->regs[0];
128 	sp -= 32;
129 
130 	/* This is the X/Open sanctioned signal stack switching.  */
131 	if ((ka->sa.sa_flags & SA_ONSTACK) && (!on_sig_stack(sp)))
132 		sp = current->sas_ss_sp + current->sas_ss_size;
133 
134 	return (void __user*)((sp - frame_size) & ~7);
135 }
136 
137 asmlinkage long
score_sigaltstack(struct pt_regs * regs)138 score_sigaltstack(struct pt_regs *regs)
139 {
140 	const stack_t __user *uss = (const stack_t __user *) regs->regs[4];
141 	stack_t __user *uoss = (stack_t __user *) regs->regs[5];
142 	unsigned long usp = regs->regs[0];
143 
144 	return do_sigaltstack(uss, uoss, usp);
145 }
146 
147 asmlinkage long
score_rt_sigreturn(struct pt_regs * regs)148 score_rt_sigreturn(struct pt_regs *regs)
149 {
150 	struct rt_sigframe __user *frame;
151 	sigset_t set;
152 	stack_t st;
153 	int sig;
154 
155 	frame = (struct rt_sigframe __user *) regs->regs[0];
156 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
157 		goto badframe;
158 	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
159 		goto badframe;
160 
161 	sigdelsetmask(&set, ~_BLOCKABLE);
162 	spin_lock_irq(&current->sighand->siglock);
163 	current->blocked = set;
164 	recalc_sigpending();
165 	spin_unlock_irq(&current->sighand->siglock);
166 
167 	sig = restore_sigcontext(regs, &frame->rs_uc.uc_mcontext);
168 	if (sig < 0)
169 		goto badframe;
170 	else if (sig)
171 		force_sig(sig, current);
172 
173 	if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
174 		goto badframe;
175 
176 	/* It is more difficult to avoid calling this function than to
177 	   call it and ignore errors.  */
178 	do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]);
179 
180 	__asm__ __volatile__(
181 		"mv\tr0, %0\n\t"
182 		"la\tr8, syscall_exit\n\t"
183 		"br\tr8\n\t"
184 		: : "r" (regs) : "r8");
185 
186 badframe:
187 	force_sig(SIGSEGV, current);
188 
189 	return 0;
190 }
191 
setup_rt_frame(struct k_sigaction * ka,struct pt_regs * regs,int signr,sigset_t * set,siginfo_t * info)192 static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
193 		int signr, sigset_t *set, siginfo_t *info)
194 {
195 	struct rt_sigframe __user *frame;
196 	int err = 0;
197 
198 	frame = get_sigframe(ka, regs, sizeof(*frame));
199 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
200 		goto give_sigsegv;
201 
202 	/*
203 	 * Set up the return code ...
204 	 *
205 	 *         li      v0, __NR_rt_sigreturn
206 	 *         syscall
207 	 */
208 	err |= __put_user(0x87788000 + __NR_rt_sigreturn*2,
209 			frame->rs_code + 0);
210 	err |= __put_user(0x80008002, frame->rs_code + 1);
211 	flush_cache_sigtramp((unsigned long) frame->rs_code);
212 
213 	err |= copy_siginfo_to_user(&frame->rs_info, info);
214 	err |= __put_user(0, &frame->rs_uc.uc_flags);
215 	err |= __put_user(NULL, &frame->rs_uc.uc_link);
216 	err |= __put_user((void __user *)current->sas_ss_sp,
217 				&frame->rs_uc.uc_stack.ss_sp);
218 	err |= __put_user(sas_ss_flags(regs->regs[0]),
219 				&frame->rs_uc.uc_stack.ss_flags);
220 	err |= __put_user(current->sas_ss_size,
221 				&frame->rs_uc.uc_stack.ss_size);
222 	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
223 	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
224 
225 	if (err)
226 		goto give_sigsegv;
227 
228 	regs->regs[0] = (unsigned long) frame;
229 	regs->regs[3] = (unsigned long) frame->rs_code;
230 	regs->regs[4] = signr;
231 	regs->regs[5] = (unsigned long) &frame->rs_info;
232 	regs->regs[6] = (unsigned long) &frame->rs_uc;
233 	regs->regs[29] = (unsigned long) ka->sa.sa_handler;
234 	regs->cp0_epc = (unsigned long) ka->sa.sa_handler;
235 
236 	return 0;
237 
238 give_sigsegv:
239 	if (signr == SIGSEGV)
240 		ka->sa.sa_handler = SIG_DFL;
241 	force_sig(SIGSEGV, current);
242 	return -EFAULT;
243 }
244 
handle_signal(unsigned long sig,siginfo_t * info,struct k_sigaction * ka,sigset_t * oldset,struct pt_regs * regs)245 static int handle_signal(unsigned long sig, siginfo_t *info,
246 	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
247 {
248 	int ret;
249 
250 	if (regs->is_syscall) {
251 		switch (regs->regs[4]) {
252 		case ERESTART_RESTARTBLOCK:
253 		case ERESTARTNOHAND:
254 			regs->regs[4] = EINTR;
255 			break;
256 		case ERESTARTSYS:
257 			if (!(ka->sa.sa_flags & SA_RESTART)) {
258 				regs->regs[4] = EINTR;
259 				break;
260 			}
261 		case ERESTARTNOINTR:
262 			regs->regs[4] = regs->orig_r4;
263 			regs->regs[7] = regs->orig_r7;
264 			regs->cp0_epc -= 8;
265 		}
266 
267 		regs->is_syscall = 0;
268 	}
269 
270 	/*
271 	 * Set up the stack frame
272 	 */
273 	ret = setup_rt_frame(ka, regs, sig, oldset, info);
274 
275 	spin_lock_irq(&current->sighand->siglock);
276 	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
277 	if (!(ka->sa.sa_flags & SA_NODEFER))
278 		sigaddset(&current->blocked, sig);
279 	recalc_sigpending();
280 	spin_unlock_irq(&current->sighand->siglock);
281 
282 	return ret;
283 }
284 
do_signal(struct pt_regs * regs)285 static void do_signal(struct pt_regs *regs)
286 {
287 	struct k_sigaction ka;
288 	sigset_t *oldset;
289 	siginfo_t info;
290 	int signr;
291 
292 	/*
293 	 * We want the common case to go fast, which is why we may in certain
294 	 * cases get here from kernel mode. Just return without doing anything
295 	 * if so.
296 	 */
297 	if (!user_mode(regs))
298 		return;
299 
300 	if (test_thread_flag(TIF_RESTORE_SIGMASK))
301 		oldset = &current->saved_sigmask;
302 	else
303 		oldset = &current->blocked;
304 
305 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
306 	if (signr > 0) {
307 		/* Actually deliver the signal.  */
308 		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
309 			/*
310 			 * A signal was successfully delivered; the saved
311 			 * sigmask will have been stored in the signal frame,
312 			 * and will be restored by sigreturn, so we can simply
313 			 * clear the TIF_RESTORE_SIGMASK flag.
314 			 */
315 			if (test_thread_flag(TIF_RESTORE_SIGMASK))
316 				clear_thread_flag(TIF_RESTORE_SIGMASK);
317 		}
318 
319 		return;
320 	}
321 
322 	if (regs->is_syscall) {
323 		if (regs->regs[4] == ERESTARTNOHAND ||
324 		    regs->regs[4] == ERESTARTSYS ||
325 		    regs->regs[4] == ERESTARTNOINTR) {
326 			regs->regs[4] = regs->orig_r4;
327 			regs->regs[7] = regs->orig_r7;
328 			regs->cp0_epc -= 8;
329 		}
330 
331 		if (regs->regs[4] == ERESTART_RESTARTBLOCK) {
332 			regs->regs[27] = __NR_restart_syscall;
333 			regs->regs[4] = regs->orig_r4;
334 			regs->regs[7] = regs->orig_r7;
335 			regs->cp0_epc -= 8;
336 		}
337 
338 		regs->is_syscall = 0;	/* Don't deal with this again.  */
339 	}
340 
341 	/*
342 	 * If there's no signal to deliver, we just put the saved sigmask
343 	 * back
344 	 */
345 	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
346 		clear_thread_flag(TIF_RESTORE_SIGMASK);
347 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
348 	}
349 }
350 
351 /*
352  * notification of userspace execution resumption
353  * - triggered by the TIF_WORK_MASK flags
354  */
do_notify_resume(struct pt_regs * regs,void * unused,__u32 thread_info_flags)355 asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
356 				__u32 thread_info_flags)
357 {
358 	/* deal with pending signal delivery */
359 	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
360 		do_signal(regs);
361 }
362