• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  linux/arch/m32r/kernel/signal.c
3  *
4  *  Copyright (c) 2003  Hitoshi Yamamoto
5  *
6  *  Taken from i386 version.
7  *  Copyright (C) 1991, 1992  Linus Torvalds
8  *
9  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
10  *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
11  */
12 
13 #include <linux/sched.h>
14 #include <linux/mm.h>
15 #include <linux/smp.h>
16 #include <linux/kernel.h>
17 #include <linux/signal.h>
18 #include <linux/errno.h>
19 #include <linux/wait.h>
20 #include <linux/unistd.h>
21 #include <linux/stddef.h>
22 #include <linux/personality.h>
23 #include <linux/freezer.h>
24 #include <asm/cacheflush.h>
25 #include <asm/ucontext.h>
26 #include <asm/uaccess.h>
27 
28 #define DEBUG_SIG 0
29 
30 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
31 
32 int do_signal(struct pt_regs *, sigset_t *);
33 
34 asmlinkage int
sys_rt_sigsuspend(sigset_t __user * unewset,size_t sigsetsize,unsigned long r2,unsigned long r3,unsigned long r4,unsigned long r5,unsigned long r6,struct pt_regs * regs)35 sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
36 		  unsigned long r2, unsigned long r3, unsigned long r4,
37 		  unsigned long r5, unsigned long r6, struct pt_regs *regs)
38 {
39 	sigset_t newset;
40 
41 	/* XXX: Don't preclude handling different sized sigset_t's.  */
42 	if (sigsetsize != sizeof(sigset_t))
43 		return -EINVAL;
44 
45 	if (copy_from_user(&newset, unewset, sizeof(newset)))
46 		return -EFAULT;
47 	sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
48 
49 	spin_lock_irq(&current->sighand->siglock);
50 	current->saved_sigmask = current->blocked;
51 	current->blocked = newset;
52 	recalc_sigpending();
53 	spin_unlock_irq(&current->sighand->siglock);
54 
55 	current->state = TASK_INTERRUPTIBLE;
56 	schedule();
57 	set_thread_flag(TIF_RESTORE_SIGMASK);
58 	return -ERESTARTNOHAND;
59 }
60 
61 asmlinkage int
sys_sigaltstack(const stack_t __user * uss,stack_t __user * uoss,unsigned long r2,unsigned long r3,unsigned long r4,unsigned long r5,unsigned long r6,struct pt_regs * regs)62 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
63 		unsigned long r2, unsigned long r3, unsigned long r4,
64 		unsigned long r5, unsigned long r6, struct pt_regs *regs)
65 {
66 	return do_sigaltstack(uss, uoss, regs->spu);
67 }
68 
69 
70 /*
71  * Do a signal return; undo the signal stack.
72  */
73 
74 struct rt_sigframe
75 {
76 	int sig;
77 	struct siginfo __user *pinfo;
78 	void __user *puc;
79 	struct siginfo info;
80 	struct ucontext uc;
81 //	struct _fpstate fpstate;
82 };
83 
84 static int
restore_sigcontext(struct pt_regs * regs,struct sigcontext __user * sc,int * r0_p)85 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
86 		   int *r0_p)
87 {
88 	unsigned int err = 0;
89 
90 	/* Always make any pending restarted system calls return -EINTR */
91 	current_thread_info()->restart_block.fn = do_no_restart_syscall;
92 
93 #define COPY(x)		err |= __get_user(regs->x, &sc->sc_##x)
94 	COPY(r4);
95 	COPY(r5);
96 	COPY(r6);
97 	COPY(pt_regs);
98 	/* COPY(r0); Skip r0 */
99 	COPY(r1);
100 	COPY(r2);
101 	COPY(r3);
102 	COPY(r7);
103 	COPY(r8);
104 	COPY(r9);
105 	COPY(r10);
106 	COPY(r11);
107 	COPY(r12);
108 	COPY(acc0h);
109 	COPY(acc0l);
110 	COPY(acc1h);		/* ISA_DSP_LEVEL2 only */
111 	COPY(acc1l);		/* ISA_DSP_LEVEL2 only */
112 	COPY(psw);
113 	COPY(bpc);
114 	COPY(bbpsw);
115 	COPY(bbpc);
116 	COPY(spu);
117 	COPY(fp);
118 	COPY(lr);
119 	COPY(spi);
120 #undef COPY
121 
122 	regs->syscall_nr = -1;	/* disable syscall checks */
123 	err |= __get_user(*r0_p, &sc->sc_r0);
124 
125 	return err;
126 }
127 
128 asmlinkage int
sys_rt_sigreturn(unsigned long r0,unsigned long r1,unsigned long r2,unsigned long r3,unsigned long r4,unsigned long r5,unsigned long r6,struct pt_regs * regs)129 sys_rt_sigreturn(unsigned long r0, unsigned long r1,
130 		 unsigned long r2, unsigned long r3, unsigned long r4,
131 		 unsigned long r5, unsigned long r6, struct pt_regs *regs)
132 {
133 	struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->spu;
134 	sigset_t set;
135 	int result;
136 
137 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
138 		goto badframe;
139 	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
140 		goto badframe;
141 
142 	sigdelsetmask(&set, ~_BLOCKABLE);
143 	spin_lock_irq(&current->sighand->siglock);
144 	current->blocked = set;
145 	recalc_sigpending();
146 	spin_unlock_irq(&current->sighand->siglock);
147 
148 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &result))
149 		goto badframe;
150 
151 	if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->spu) == -EFAULT)
152 		goto badframe;
153 
154 	return result;
155 
156 badframe:
157 	force_sig(SIGSEGV, current);
158 	return 0;
159 }
160 
161 /*
162  * Set up a signal frame.
163  */
164 
165 static int
setup_sigcontext(struct sigcontext __user * sc,struct pt_regs * regs,unsigned long mask)166 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
167 	         unsigned long mask)
168 {
169 	int err = 0;
170 
171 #define COPY(x)	err |= __put_user(regs->x, &sc->sc_##x)
172 	COPY(r4);
173 	COPY(r5);
174 	COPY(r6);
175 	COPY(pt_regs);
176 	COPY(r0);
177 	COPY(r1);
178 	COPY(r2);
179 	COPY(r3);
180 	COPY(r7);
181 	COPY(r8);
182 	COPY(r9);
183 	COPY(r10);
184 	COPY(r11);
185 	COPY(r12);
186 	COPY(acc0h);
187 	COPY(acc0l);
188 	COPY(acc1h);		/* ISA_DSP_LEVEL2 only */
189 	COPY(acc1l);		/* ISA_DSP_LEVEL2 only */
190 	COPY(psw);
191 	COPY(bpc);
192 	COPY(bbpsw);
193 	COPY(bbpc);
194 	COPY(spu);
195 	COPY(fp);
196 	COPY(lr);
197 	COPY(spi);
198 #undef COPY
199 
200 	err |= __put_user(mask, &sc->oldmask);
201 
202 	return err;
203 }
204 
205 /*
206  * Determine which stack to use..
207  */
208 static inline void __user *
get_sigframe(struct k_sigaction * ka,unsigned long sp,size_t frame_size)209 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
210 {
211 	/* This is the X/Open sanctioned signal stack switching.  */
212 	if (ka->sa.sa_flags & SA_ONSTACK) {
213 		if (sas_ss_flags(sp) == 0)
214 			sp = current->sas_ss_sp + current->sas_ss_size;
215 	}
216 
217 	return (void __user *)((sp - frame_size) & -8ul);
218 }
219 
setup_rt_frame(int sig,struct k_sigaction * ka,siginfo_t * info,sigset_t * set,struct pt_regs * regs)220 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
221 			   sigset_t *set, struct pt_regs *regs)
222 {
223 	struct rt_sigframe __user *frame;
224 	int err = 0;
225 	int signal;
226 
227 	frame = get_sigframe(ka, regs->spu, sizeof(*frame));
228 
229 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
230 		goto give_sigsegv;
231 
232 	signal = current_thread_info()->exec_domain
233 		&& current_thread_info()->exec_domain->signal_invmap
234 		&& sig < 32
235 		? current_thread_info()->exec_domain->signal_invmap[sig]
236 		: sig;
237 
238 	err |= __put_user(signal, &frame->sig);
239 	if (err)
240 		goto give_sigsegv;
241 
242 	err |= __put_user(&frame->info, &frame->pinfo);
243 	err |= __put_user(&frame->uc, &frame->puc);
244 	err |= copy_siginfo_to_user(&frame->info, info);
245 	if (err)
246 		goto give_sigsegv;
247 
248 	/* Create the ucontext.  */
249 	err |= __put_user(0, &frame->uc.uc_flags);
250 	err |= __put_user(0, &frame->uc.uc_link);
251 	err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
252 	err |= __put_user(sas_ss_flags(regs->spu),
253 			  &frame->uc.uc_stack.ss_flags);
254 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
255 	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
256 	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
257 	if (err)
258 		goto give_sigsegv;
259 
260 	/* Set up to return from userspace.  */
261 	regs->lr = (unsigned long)ka->sa.sa_restorer;
262 
263 	/* Set up registers for signal handler */
264 	regs->spu = (unsigned long)frame;
265 	regs->r0 = signal;	/* Arg for signal handler */
266 	regs->r1 = (unsigned long)&frame->info;
267 	regs->r2 = (unsigned long)&frame->uc;
268 	regs->bpc = (unsigned long)ka->sa.sa_handler;
269 
270 	set_fs(USER_DS);
271 
272 #if DEBUG_SIG
273 	printk("SIG deliver (%s:%d): sp=%p pc=%p\n",
274 		current->comm, current->pid, frame, regs->pc);
275 #endif
276 
277 	return;
278 
279 give_sigsegv:
280 	force_sigsegv(sig, current);
281 }
282 
283 /*
284  * OK, we're invoking a handler
285  */
286 
287 static void
handle_signal(unsigned long sig,struct k_sigaction * ka,siginfo_t * info,sigset_t * oldset,struct pt_regs * regs)288 handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
289 	      sigset_t *oldset, struct pt_regs *regs)
290 {
291 	unsigned short inst;
292 
293 	/* Are we from a system call? */
294 	if (regs->syscall_nr >= 0) {
295 		/* If so, check system call restarting.. */
296 		switch (regs->r0) {
297 		        case -ERESTART_RESTARTBLOCK:
298 			case -ERESTARTNOHAND:
299 				regs->r0 = -EINTR;
300 				break;
301 
302 			case -ERESTARTSYS:
303 				if (!(ka->sa.sa_flags & SA_RESTART)) {
304 					regs->r0 = -EINTR;
305 					break;
306 				}
307 			/* fallthrough */
308 			case -ERESTARTNOINTR:
309 				regs->r0 = regs->orig_r0;
310 				inst = *(unsigned short *)(regs->bpc - 2);
311 				if ((inst & 0xfff0) == 0x10f0)	/* trap ? */
312 					regs->bpc -= 2;
313 				else
314 					regs->bpc -= 4;
315 		}
316 	}
317 
318 	/* Set up the stack frame */
319 	setup_rt_frame(sig, ka, info, oldset, regs);
320 
321 	spin_lock_irq(&current->sighand->siglock);
322 	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
323 	if (!(ka->sa.sa_flags & SA_NODEFER))
324 		sigaddset(&current->blocked,sig);
325 	recalc_sigpending();
326 	spin_unlock_irq(&current->sighand->siglock);
327 }
328 
329 /*
330  * Note that 'init' is a special process: it doesn't get signals it doesn't
331  * want to handle. Thus you cannot kill init even with a SIGKILL even by
332  * mistake.
333  */
do_signal(struct pt_regs * regs,sigset_t * oldset)334 int do_signal(struct pt_regs *regs, sigset_t *oldset)
335 {
336 	siginfo_t info;
337 	int signr;
338 	struct k_sigaction ka;
339 	unsigned short inst;
340 
341 	/*
342 	 * We want the common case to go fast, which
343 	 * is why we may in certain cases get here from
344 	 * kernel mode. Just return without doing anything
345 	 * if so.
346 	 */
347 	if (!user_mode(regs))
348 		return 1;
349 
350 	if (try_to_freeze())
351 		goto no_signal;
352 
353 	if (!oldset)
354 		oldset = &current->blocked;
355 
356 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
357 	if (signr > 0) {
358 		/* Re-enable any watchpoints before delivering the
359 		 * signal to user space. The processor register will
360 		 * have been cleared if the watchpoint triggered
361 		 * inside the kernel.
362 		 */
363 
364 		/* Whee!  Actually deliver the signal.  */
365 		handle_signal(signr, &ka, &info, oldset, regs);
366 		return 1;
367 	}
368 
369  no_signal:
370 	/* Did we come from a system call? */
371 	if (regs->syscall_nr >= 0) {
372 		/* Restart the system call - no handlers present */
373 		if (regs->r0 == -ERESTARTNOHAND ||
374 		    regs->r0 == -ERESTARTSYS ||
375 		    regs->r0 == -ERESTARTNOINTR) {
376 			regs->r0 = regs->orig_r0;
377 			inst = *(unsigned short *)(regs->bpc - 2);
378 			if ((inst & 0xfff0) == 0x10f0)	/* trap ? */
379 				regs->bpc -= 2;
380 			else
381 				regs->bpc -= 4;
382 		}
383 		if (regs->r0 == -ERESTART_RESTARTBLOCK){
384 			regs->r0 = regs->orig_r0;
385 			regs->r7 = __NR_restart_syscall;
386 			inst = *(unsigned short *)(regs->bpc - 2);
387 			if ((inst & 0xfff0) == 0x10f0)	/* trap ? */
388 				regs->bpc -= 2;
389 			else
390 				regs->bpc -= 4;
391 		}
392 	}
393 	return 0;
394 }
395 
396 /*
397  * notification of userspace execution resumption
398  * - triggered by current->work.notify_resume
399  */
do_notify_resume(struct pt_regs * regs,sigset_t * oldset,__u32 thread_info_flags)400 void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
401 		      __u32 thread_info_flags)
402 {
403 	/* Pending single-step? */
404 	if (thread_info_flags & _TIF_SINGLESTEP)
405 		clear_thread_flag(TIF_SINGLESTEP);
406 
407 	/* deal with pending signal delivery */
408 	if (thread_info_flags & _TIF_SIGPENDING)
409 		do_signal(regs,oldset);
410 
411 	clear_thread_flag(TIF_IRET);
412 }
413