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