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