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