]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - arch/sh/kernel/signal_64.c
kbuild: use INSTALLKERNEL to select customized installkernel script
[mirror_ubuntu-artful-kernel.git] / arch / sh / kernel / signal_64.c
CommitLineData
1da177e4 1/*
a23ba435 2 * arch/sh/kernel/signal_64.c
1da177e4
LT
3 *
4 * Copyright (C) 2000, 2001 Paolo Alberelli
6ac03437 5 * Copyright (C) 2003 - 2008 Paul Mundt
1da177e4
LT
6 * Copyright (C) 2004 Richard Curnow
7 *
a23ba435
PM
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
1da177e4
LT
11 */
12#include <linux/rwsem.h>
13#include <linux/sched.h>
14#include <linux/mm.h>
15#include <linux/smp.h>
1da177e4
LT
16#include <linux/kernel.h>
17#include <linux/signal.h>
18#include <linux/errno.h>
19#include <linux/wait.h>
20#include <linux/personality.h>
7dfb7103 21#include <linux/freezer.h>
1da177e4
LT
22#include <linux/ptrace.h>
23#include <linux/unistd.h>
24#include <linux/stddef.h>
ab99c733 25#include <linux/tracehook.h>
1da177e4
LT
26#include <asm/ucontext.h>
27#include <asm/uaccess.h>
28#include <asm/pgtable.h>
f7a7b153 29#include <asm/cacheflush.h>
50387b3e 30#include <asm/fpu.h>
1da177e4
LT
31
32#define REG_RET 9
33#define REG_ARG1 2
34#define REG_ARG2 3
35#define REG_ARG3 4
36#define REG_SP 15
37#define REG_PR 18
38#define REF_REG_RET regs->regs[REG_RET]
39#define REF_REG_SP regs->regs[REG_SP]
40#define DEREF_REG_PR regs->regs[REG_PR]
41
42#define DEBUG_SIG 0
43
44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
45
6ac03437 46static int
8a80a5e9
PM
47handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
48 sigset_t *oldset, struct pt_regs * regs);
49
94e2fb3d
PM
50static inline void
51handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
52{
53 /* If we're not from a syscall, bail out */
54 if (regs->syscall_nr < 0)
55 return;
56
57 /* check for system call restart.. */
58 switch (regs->regs[REG_RET]) {
59 case -ERESTART_RESTARTBLOCK:
60 case -ERESTARTNOHAND:
61 no_system_call_restart:
62 regs->regs[REG_RET] = -EINTR;
94e2fb3d
PM
63 break;
64
65 case -ERESTARTSYS:
66 if (!(sa->sa_flags & SA_RESTART))
67 goto no_system_call_restart;
68 /* fallthrough */
69 case -ERESTARTNOINTR:
70 /* Decode syscall # */
71 regs->regs[REG_RET] = regs->syscall_nr;
72 regs->pc -= 4;
73 break;
74 }
75}
76
ab99c733
PM
77/*
78 * Note that 'init' is a special process: it doesn't get signals it doesn't
79 * want to handle. Thus you cannot kill init even with a SIGKILL even by
80 * mistake.
81 *
82 * Note that we go through the signals twice: once to check the signals that
83 * the kernel can handle, and then we build all the user-level signal handling
84 * stack-frames in one go after that.
85 */
86static int do_signal(struct pt_regs *regs, sigset_t *oldset)
87{
88 siginfo_t info;
89 int signr;
90 struct k_sigaction ka;
91
92 /*
93 * We want the common case to go fast, which
94 * is why we may in certain cases get here from
95 * kernel mode. Just return without doing anything
96 * if so.
97 */
98 if (!user_mode(regs))
99 return 1;
100
101 if (try_to_freeze())
102 goto no_signal;
103
104 if (test_thread_flag(TIF_RESTORE_SIGMASK))
105 oldset = &current->saved_sigmask;
106 else if (!oldset)
107 oldset = &current->blocked;
108
109 signr = get_signal_to_deliver(&info, &ka, regs, 0);
ab99c733 110 if (signr > 0) {
03f07876 111 handle_syscall_restart(regs, &ka.sa);
94e2fb3d 112
ab99c733 113 /* Whee! Actually deliver the signal. */
6ac03437
PM
114 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
115 /*
116 * If a signal was successfully delivered, the
117 * saved sigmask is in its frame, and we can
118 * clear the TIF_RESTORE_SIGMASK flag.
119 */
120 if (test_thread_flag(TIF_RESTORE_SIGMASK))
121 clear_thread_flag(TIF_RESTORE_SIGMASK);
122
123 tracehook_signal_handler(signr, &info, &ka, regs, 0);
124 return 1;
125 }
ab99c733
PM
126 }
127
128no_signal:
129 /* Did we come from a system call? */
130 if (regs->syscall_nr >= 0) {
131 /* Restart the system call - no handlers present */
132 switch (regs->regs[REG_RET]) {
133 case -ERESTARTNOHAND:
134 case -ERESTARTSYS:
135 case -ERESTARTNOINTR:
136 /* Decode Syscall # */
137 regs->regs[REG_RET] = regs->syscall_nr;
138 regs->pc -= 4;
139 break;
140
141 case -ERESTART_RESTARTBLOCK:
142 regs->regs[REG_RET] = __NR_restart_syscall;
143 regs->pc -= 4;
144 break;
145 }
146 }
147
148 /* No signal to deliver -- put the saved sigmask back */
149 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
150 clear_thread_flag(TIF_RESTORE_SIGMASK);
151 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
152 }
153
154 return 0;
155}
1da177e4
LT
156
157/*
158 * Atomically swap in the new signal mask, and wait for a signal.
159 */
1da177e4
LT
160asmlinkage int
161sys_sigsuspend(old_sigset_t mask,
162 unsigned long r3, unsigned long r4, unsigned long r5,
163 unsigned long r6, unsigned long r7,
164 struct pt_regs * regs)
165{
166 sigset_t saveset;
167
168 mask &= _BLOCKABLE;
169 spin_lock_irq(&current->sighand->siglock);
170 saveset = current->blocked;
171 siginitset(&current->blocked, mask);
172 recalc_sigpending();
173 spin_unlock_irq(&current->sighand->siglock);
174
175 REF_REG_RET = -EINTR;
176 while (1) {
177 current->state = TASK_INTERRUPTIBLE;
178 schedule();
179 regs->pc += 4; /* because sys_sigreturn decrements the pc */
180 if (do_signal(regs, &saveset)) {
181 /* pc now points at signal handler. Need to decrement
182 it because entry.S will increment it. */
183 regs->pc -= 4;
184 return -EINTR;
185 }
186 }
187}
188
189asmlinkage int
190sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
191 unsigned long r4, unsigned long r5, unsigned long r6,
192 unsigned long r7,
193 struct pt_regs * regs)
194{
195 sigset_t saveset, newset;
196
197 /* XXX: Don't preclude handling different sized sigset_t's. */
198 if (sigsetsize != sizeof(sigset_t))
199 return -EINVAL;
200
201 if (copy_from_user(&newset, unewset, sizeof(newset)))
202 return -EFAULT;
203 sigdelsetmask(&newset, ~_BLOCKABLE);
204 spin_lock_irq(&current->sighand->siglock);
205 saveset = current->blocked;
206 current->blocked = newset;
207 recalc_sigpending();
208 spin_unlock_irq(&current->sighand->siglock);
209
210 REF_REG_RET = -EINTR;
211 while (1) {
212 current->state = TASK_INTERRUPTIBLE;
213 schedule();
214 regs->pc += 4; /* because sys_sigreturn decrements the pc */
215 if (do_signal(regs, &saveset)) {
216 /* pc now points at signal handler. Need to decrement
217 it because entry.S will increment it. */
218 regs->pc -= 4;
219 return -EINTR;
220 }
221 }
222}
223
224asmlinkage int
225sys_sigaction(int sig, const struct old_sigaction __user *act,
226 struct old_sigaction __user *oact)
227{
228 struct k_sigaction new_ka, old_ka;
229 int ret;
230
231 if (act) {
232 old_sigset_t mask;
233 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
234 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
235 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
236 return -EFAULT;
237 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
238 __get_user(mask, &act->sa_mask);
239 siginitset(&new_ka.sa.sa_mask, mask);
240 }
241
242 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
243
244 if (!ret && oact) {
245 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
246 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
247 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
248 return -EFAULT;
249 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
250 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
251 }
252
253 return ret;
254}
255
256asmlinkage int
257sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
258 unsigned long r4, unsigned long r5, unsigned long r6,
259 unsigned long r7,
260 struct pt_regs * regs)
261{
262 return do_sigaltstack(uss, uoss, REF_REG_SP);
263}
264
1da177e4
LT
265/*
266 * Do a signal return; undo the signal stack.
267 */
94e2fb3d 268struct sigframe {
1da177e4
LT
269 struct sigcontext sc;
270 unsigned long extramask[_NSIG_WORDS-1];
271 long long retcode[2];
272};
273
94e2fb3d 274struct rt_sigframe {
1da177e4
LT
275 struct siginfo __user *pinfo;
276 void *puc;
277 struct siginfo info;
278 struct ucontext uc;
279 long long retcode[2];
280};
281
282#ifdef CONFIG_SH_FPU
283static inline int
284restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
285{
286 int err = 0;
287 int fpvalid;
288
289 err |= __get_user (fpvalid, &sc->sc_fpvalid);
290 conditional_used_math(fpvalid);
291 if (! fpvalid)
292 return err;
293
294 if (current == last_task_used_math) {
295 last_task_used_math = NULL;
296 regs->sr |= SR_FD;
297 }
298
299 err |= __copy_from_user(&current->thread.fpu.hard, &sc->sc_fpregs[0],
300 (sizeof(long long) * 32) + (sizeof(int) * 1));
301
302 return err;
303}
304
305static inline int
306setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
307{
308 int err = 0;
309 int fpvalid;
310
311 fpvalid = !!used_math();
312 err |= __put_user(fpvalid, &sc->sc_fpvalid);
313 if (! fpvalid)
314 return err;
315
316 if (current == last_task_used_math) {
600ee240 317 enable_fpu();
332fd57b 318 save_fpu(current, regs);
600ee240 319 disable_fpu();
1da177e4
LT
320 last_task_used_math = NULL;
321 regs->sr |= SR_FD;
322 }
323
324 err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.fpu.hard,
325 (sizeof(long long) * 32) + (sizeof(int) * 1));
326 clear_used_math();
327
328 return err;
329}
330#else
331static inline int
332restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
f7a7b153
PM
333{
334 return 0;
335}
1da177e4
LT
336static inline int
337setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
f7a7b153
PM
338{
339 return 0;
340}
1da177e4
LT
341#endif
342
343static int
344restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, long long *r2_p)
345{
346 unsigned int err = 0;
347 unsigned long long current_sr, new_sr;
348#define SR_MASK 0xffff8cfd
349
350#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
351
352 COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]);
353 COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]);
354 COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]);
355 COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]);
356 COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]);
357 COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]);
358 COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]);
359 COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]);
360 COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]);
361 COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]);
362 COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]);
363 COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]);
364 COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]);
365 COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]);
366 COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]);
367 COPY(regs[60]); COPY(regs[61]); COPY(regs[62]);
368 COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]);
369 COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]);
370
371 /* Prevent the signal handler manipulating SR in a way that can
372 crash the kernel. i.e. only allow S, Q, M, PR, SZ, FR to be
373 modified */
374 current_sr = regs->sr;
375 err |= __get_user(new_sr, &sc->sc_sr);
376 regs->sr &= SR_MASK;
377 regs->sr |= (new_sr & ~SR_MASK);
378
379 COPY(pc);
380
381#undef COPY
382
383 /* Must do this last in case it sets regs->sr.fd (i.e. after rest of sr
384 * has been restored above.) */
385 err |= restore_sigcontext_fpu(regs, sc);
386
387 regs->syscall_nr = -1; /* disable syscall checks */
388 err |= __get_user(*r2_p, &sc->sc_regs[REG_RET]);
389 return err;
390}
391
392asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
393 unsigned long r4, unsigned long r5,
394 unsigned long r6, unsigned long r7,
395 struct pt_regs * regs)
396{
397 struct sigframe __user *frame = (struct sigframe __user *) (long) REF_REG_SP;
398 sigset_t set;
399 long long ret;
400
1bec157a
PM
401 /* Always make any pending restarted system calls return -EINTR */
402 current_thread_info()->restart_block.fn = do_no_restart_syscall;
403
1da177e4
LT
404 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
405 goto badframe;
406
407 if (__get_user(set.sig[0], &frame->sc.oldmask)
408 || (_NSIG_WORDS > 1
409 && __copy_from_user(&set.sig[1], &frame->extramask,
410 sizeof(frame->extramask))))
411 goto badframe;
412
413 sigdelsetmask(&set, ~_BLOCKABLE);
414
415 spin_lock_irq(&current->sighand->siglock);
416 current->blocked = set;
417 recalc_sigpending();
418 spin_unlock_irq(&current->sighand->siglock);
419
420 if (restore_sigcontext(regs, &frame->sc, &ret))
421 goto badframe;
422 regs->pc -= 4;
423
424 return (int) ret;
425
426badframe:
427 force_sig(SIGSEGV, current);
428 return 0;
429}
430
431asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
432 unsigned long r4, unsigned long r5,
433 unsigned long r6, unsigned long r7,
434 struct pt_regs * regs)
435{
436 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP;
437 sigset_t set;
438 stack_t __user st;
439 long long ret;
440
1bec157a
PM
441 /* Always make any pending restarted system calls return -EINTR */
442 current_thread_info()->restart_block.fn = do_no_restart_syscall;
443
1da177e4
LT
444 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
445 goto badframe;
446
447 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
448 goto badframe;
449
450 sigdelsetmask(&set, ~_BLOCKABLE);
451 spin_lock_irq(&current->sighand->siglock);
452 current->blocked = set;
453 recalc_sigpending();
454 spin_unlock_irq(&current->sighand->siglock);
455
456 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret))
457 goto badframe;
458 regs->pc -= 4;
459
460 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
461 goto badframe;
462 /* It is more difficult to avoid calling this function than to
463 call it and ignore errors. */
464 do_sigaltstack(&st, NULL, REF_REG_SP);
465
466 return (int) ret;
467
468badframe:
469 force_sig(SIGSEGV, current);
470 return 0;
471}
472
473/*
474 * Set up a signal frame.
475 */
1da177e4
LT
476static int
477setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
478 unsigned long mask)
479{
480 int err = 0;
481
482 /* Do this first, otherwise is this sets sr->fd, that value isn't preserved. */
483 err |= setup_sigcontext_fpu(regs, sc);
484
485#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
486
487 COPY(regs[0]); COPY(regs[1]); COPY(regs[2]); COPY(regs[3]);
488 COPY(regs[4]); COPY(regs[5]); COPY(regs[6]); COPY(regs[7]);
489 COPY(regs[8]); COPY(regs[9]); COPY(regs[10]); COPY(regs[11]);
490 COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]);
491 COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]);
492 COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]);
493 COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]);
494 COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]);
495 COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]);
496 COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]);
497 COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]);
498 COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]);
499 COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]);
500 COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]);
501 COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]);
502 COPY(regs[60]); COPY(regs[61]); COPY(regs[62]);
503 COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]);
504 COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]);
505 COPY(sr); COPY(pc);
506
507#undef COPY
508
509 err |= __put_user(mask, &sc->oldmask);
510
511 return err;
512}
513
514/*
515 * Determine which stack to use..
516 */
517static inline void __user *
518get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
519{
d09042da 520 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
1da177e4
LT
521 sp = current->sas_ss_sp + current->sas_ss_size;
522
523 return (void __user *)((sp - frame_size) & -8ul);
524}
525
526void sa_default_restorer(void); /* See comments below */
527void sa_default_rt_restorer(void); /* See comments below */
528
6ac03437
PM
529static int setup_frame(int sig, struct k_sigaction *ka,
530 sigset_t *set, struct pt_regs *regs)
1da177e4
LT
531{
532 struct sigframe __user *frame;
533 int err = 0;
534 int signal;
535
536 frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
537
538 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
539 goto give_sigsegv;
540
541 signal = current_thread_info()->exec_domain
542 && current_thread_info()->exec_domain->signal_invmap
543 && sig < 32
544 ? current_thread_info()->exec_domain->signal_invmap[sig]
545 : sig;
546
547 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
548
549 /* Give up earlier as i386, in case */
550 if (err)
551 goto give_sigsegv;
552
553 if (_NSIG_WORDS > 1) {
554 err |= __copy_to_user(frame->extramask, &set->sig[1],
555 sizeof(frame->extramask)); }
556
557 /* Give up earlier as i386, in case */
558 if (err)
559 goto give_sigsegv;
560
561 /* Set up to return from userspace. If provided, use a stub
562 already in userspace. */
563 if (ka->sa.sa_flags & SA_RESTORER) {
1da177e4
LT
564 /*
565 * On SH5 all edited pointers are subject to NEFF
566 */
c7914834
PM
567 DEREF_REG_PR = neff_sign_extend((unsigned long)
568 ka->sa.sa_restorer | 0x1);
1da177e4
LT
569 } else {
570 /*
571 * Different approach on SH5.
572 * . Endianness independent asm code gets placed in entry.S .
573 * This is limited to four ASM instructions corresponding
574 * to two long longs in size.
575 * . err checking is done on the else branch only
576 * . flush_icache_range() is called upon __put_user() only
577 * . all edited pointers are subject to NEFF
578 * . being code, linker turns ShMedia bit on, always
579 * dereference index -1.
580 */
c7914834
PM
581 DEREF_REG_PR = neff_sign_extend((unsigned long)
582 frame->retcode | 0x01);
1da177e4
LT
583
584 if (__copy_to_user(frame->retcode,
091db045 585 (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
1da177e4
LT
586 goto give_sigsegv;
587
588 /* Cohere the trampoline with the I-cache. */
b613881e 589 flush_cache_sigtramp(DEREF_REG_PR-1);
1da177e4
LT
590 }
591
592 /*
593 * Set up registers for signal handler.
594 * All edited pointers are subject to NEFF.
595 */
c7914834 596 regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
1da177e4
LT
597 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
598
599 /* FIXME:
600 The glibc profiling support for SH-5 needs to be passed a sigcontext
601 so it can retrieve the PC. At some point during 2003 the glibc
602 support was changed to receive the sigcontext through the 2nd
603 argument, but there are still versions of libc.so in use that use
604 the 3rd argument. Until libc.so is stabilised, pass the sigcontext
605 through both 2nd and 3rd arguments.
606 */
607
608 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
609 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
610
c7914834 611 regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
1da177e4
LT
612
613 set_fs(USER_DS);
614
1da177e4 615 /* Broken %016Lx */
6ac03437
PM
616 pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
617 signal, current->comm, current->pid, frame,
618 regs->pc >> 32, regs->pc & 0xffffffff,
619 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
1da177e4 620
6ac03437 621 return 0;
1da177e4
LT
622
623give_sigsegv:
624 force_sigsegv(sig, current);
6ac03437 625 return -EFAULT;
1da177e4
LT
626}
627
6ac03437
PM
628static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
629 sigset_t *set, struct pt_regs *regs)
1da177e4
LT
630{
631 struct rt_sigframe __user *frame;
632 int err = 0;
633 int signal;
634
635 frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
636
637 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
638 goto give_sigsegv;
639
640 signal = current_thread_info()->exec_domain
641 && current_thread_info()->exec_domain->signal_invmap
642 && sig < 32
643 ? current_thread_info()->exec_domain->signal_invmap[sig]
644 : sig;
645
646 err |= __put_user(&frame->info, &frame->pinfo);
647 err |= __put_user(&frame->uc, &frame->puc);
648 err |= copy_siginfo_to_user(&frame->info, info);
649
650 /* Give up earlier as i386, in case */
651 if (err)
652 goto give_sigsegv;
653
654 /* Create the ucontext. */
655 err |= __put_user(0, &frame->uc.uc_flags);
656 err |= __put_user(0, &frame->uc.uc_link);
657 err |= __put_user((void *)current->sas_ss_sp,
658 &frame->uc.uc_stack.ss_sp);
659 err |= __put_user(sas_ss_flags(regs->regs[REG_SP]),
660 &frame->uc.uc_stack.ss_flags);
661 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
662 err |= setup_sigcontext(&frame->uc.uc_mcontext,
663 regs, set->sig[0]);
664 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
665
666 /* Give up earlier as i386, in case */
667 if (err)
668 goto give_sigsegv;
669
670 /* Set up to return from userspace. If provided, use a stub
671 already in userspace. */
672 if (ka->sa.sa_flags & SA_RESTORER) {
1da177e4
LT
673 /*
674 * On SH5 all edited pointers are subject to NEFF
675 */
c7914834
PM
676 DEREF_REG_PR = neff_sign_extend((unsigned long)
677 ka->sa.sa_restorer | 0x1);
1da177e4
LT
678 } else {
679 /*
680 * Different approach on SH5.
681 * . Endianness independent asm code gets placed in entry.S .
682 * This is limited to four ASM instructions corresponding
683 * to two long longs in size.
684 * . err checking is done on the else branch only
685 * . flush_icache_range() is called upon __put_user() only
686 * . all edited pointers are subject to NEFF
687 * . being code, linker turns ShMedia bit on, always
688 * dereference index -1.
689 */
c7914834
PM
690 DEREF_REG_PR = neff_sign_extend((unsigned long)
691 frame->retcode | 0x01);
1da177e4
LT
692
693 if (__copy_to_user(frame->retcode,
091db045 694 (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
1da177e4
LT
695 goto give_sigsegv;
696
c7914834 697 /* Cohere the trampoline with the I-cache. */
1da177e4
LT
698 flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
699 }
700
701 /*
702 * Set up registers for signal handler.
703 * All edited pointers are subject to NEFF.
704 */
c7914834 705 regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
1da177e4
LT
706 regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
707 regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
708 regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
c7914834 709 regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
1da177e4
LT
710
711 set_fs(USER_DS);
712
6ac03437
PM
713 pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
714 signal, current->comm, current->pid, frame,
715 regs->pc >> 32, regs->pc & 0xffffffff,
716 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
1da177e4 717
6ac03437 718 return 0;
1da177e4
LT
719
720give_sigsegv:
721 force_sigsegv(sig, current);
6ac03437 722 return -EFAULT;
1da177e4
LT
723}
724
725/*
726 * OK, we're invoking a handler
727 */
6ac03437 728static int
1da177e4
LT
729handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
730 sigset_t *oldset, struct pt_regs * regs)
731{
6ac03437
PM
732 int ret;
733
1da177e4
LT
734 /* Set up the stack frame */
735 if (ka->sa.sa_flags & SA_SIGINFO)
6ac03437 736 ret = setup_rt_frame(sig, ka, info, oldset, regs);
1da177e4 737 else
6ac03437
PM
738 ret = setup_frame(sig, ka, oldset, regs);
739
740 if (ka->sa.sa_flags & SA_ONESHOT)
741 ka->sa.sa_handler = SIG_DFL;
742
743 if (ret == 0) {
744 spin_lock_irq(&current->sighand->siglock);
745 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
746 if (!(ka->sa.sa_flags & SA_NODEFER))
747 sigaddset(&current->blocked,sig);
748 recalc_sigpending();
749 spin_unlock_irq(&current->sighand->siglock);
750 }
1da177e4 751
6ac03437 752 return ret;
1da177e4
LT
753}
754
ab99c733 755asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
1da177e4 756{
ab99c733
PM
757 if (thread_info_flags & _TIF_SIGPENDING)
758 do_signal(regs, 0);
c18fe9a0 759
ab99c733
PM
760 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
761 clear_thread_flag(TIF_NOTIFY_RESUME);
762 tracehook_notify_resume(regs);
ee18d64c
DH
763 if (current->replacement_session_keyring)
764 key_replace_session_keyring();
1da177e4 765 }
1da177e4 766}