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