Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/frv/kernel/signal.c
10817 views
1
/* signal.c: FRV specific bits of signal handling
2
*
3
* Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
* - Derived from arch/m68k/kernel/signal.c
6
*
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version
10
* 2 of the License, or (at your option) any later version.
11
*/
12
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/ptrace.h>
21
#include <linux/unistd.h>
22
#include <linux/personality.h>
23
#include <linux/freezer.h>
24
#include <linux/tracehook.h>
25
#include <asm/ucontext.h>
26
#include <asm/uaccess.h>
27
#include <asm/cacheflush.h>
28
29
#define DEBUG_SIG 0
30
31
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
32
33
struct fdpic_func_descriptor {
34
unsigned long text;
35
unsigned long GOT;
36
};
37
38
/*
39
* Atomically swap in the new signal mask, and wait for a signal.
40
*/
41
asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
42
{
43
mask &= _BLOCKABLE;
44
spin_lock_irq(&current->sighand->siglock);
45
current->saved_sigmask = current->blocked;
46
siginitset(&current->blocked, mask);
47
recalc_sigpending();
48
spin_unlock_irq(&current->sighand->siglock);
49
50
current->state = TASK_INTERRUPTIBLE;
51
schedule();
52
set_thread_flag(TIF_RESTORE_SIGMASK);
53
return -ERESTARTNOHAND;
54
}
55
56
asmlinkage int sys_sigaction(int sig,
57
const struct old_sigaction __user *act,
58
struct old_sigaction __user *oact)
59
{
60
struct k_sigaction new_ka, old_ka;
61
int ret;
62
63
if (act) {
64
old_sigset_t mask;
65
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
66
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
67
__get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
68
return -EFAULT;
69
__get_user(new_ka.sa.sa_flags, &act->sa_flags);
70
__get_user(mask, &act->sa_mask);
71
siginitset(&new_ka.sa.sa_mask, mask);
72
}
73
74
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
75
76
if (!ret && oact) {
77
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
78
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
79
__put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
80
return -EFAULT;
81
__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
82
__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
83
}
84
85
return ret;
86
}
87
88
asmlinkage
89
int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
90
{
91
return do_sigaltstack(uss, uoss, __frame->sp);
92
}
93
94
95
/*
96
* Do a signal return; undo the signal stack.
97
*/
98
99
struct sigframe
100
{
101
__sigrestore_t pretcode;
102
int sig;
103
struct sigcontext sc;
104
unsigned long extramask[_NSIG_WORDS-1];
105
uint32_t retcode[2];
106
};
107
108
struct rt_sigframe
109
{
110
__sigrestore_t pretcode;
111
int sig;
112
struct siginfo __user *pinfo;
113
void __user *puc;
114
struct siginfo info;
115
struct ucontext uc;
116
uint32_t retcode[2];
117
};
118
119
static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8)
120
{
121
struct user_context *user = current->thread.user;
122
unsigned long tbr, psr;
123
124
/* Always make any pending restarted system calls return -EINTR */
125
current_thread_info()->restart_block.fn = do_no_restart_syscall;
126
127
tbr = user->i.tbr;
128
psr = user->i.psr;
129
if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context)))
130
goto badframe;
131
user->i.tbr = tbr;
132
user->i.psr = psr;
133
134
restore_user_regs(user);
135
136
user->i.syscallno = -1; /* disable syscall checks */
137
138
*_gr8 = user->i.gr[8];
139
return 0;
140
141
badframe:
142
return 1;
143
}
144
145
asmlinkage int sys_sigreturn(void)
146
{
147
struct sigframe __user *frame = (struct sigframe __user *) __frame->sp;
148
sigset_t set;
149
int gr8;
150
151
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
152
goto badframe;
153
if (__get_user(set.sig[0], &frame->sc.sc_oldmask))
154
goto badframe;
155
156
if (_NSIG_WORDS > 1 &&
157
__copy_from_user(&set.sig[1], &frame->extramask, sizeof(frame->extramask)))
158
goto badframe;
159
160
sigdelsetmask(&set, ~_BLOCKABLE);
161
spin_lock_irq(&current->sighand->siglock);
162
current->blocked = set;
163
recalc_sigpending();
164
spin_unlock_irq(&current->sighand->siglock);
165
166
if (restore_sigcontext(&frame->sc, &gr8))
167
goto badframe;
168
return gr8;
169
170
badframe:
171
force_sig(SIGSEGV, current);
172
return 0;
173
}
174
175
asmlinkage int sys_rt_sigreturn(void)
176
{
177
struct rt_sigframe __user *frame = (struct rt_sigframe __user *) __frame->sp;
178
sigset_t set;
179
int gr8;
180
181
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
182
goto badframe;
183
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
184
goto badframe;
185
186
sigdelsetmask(&set, ~_BLOCKABLE);
187
spin_lock_irq(&current->sighand->siglock);
188
current->blocked = set;
189
recalc_sigpending();
190
spin_unlock_irq(&current->sighand->siglock);
191
192
if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8))
193
goto badframe;
194
195
if (do_sigaltstack(&frame->uc.uc_stack, NULL, __frame->sp) == -EFAULT)
196
goto badframe;
197
198
return gr8;
199
200
badframe:
201
force_sig(SIGSEGV, current);
202
return 0;
203
}
204
205
/*
206
* Set up a signal frame
207
*/
208
static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
209
{
210
save_user_regs(current->thread.user);
211
212
if (copy_to_user(&sc->sc_context, current->thread.user, sizeof(sc->sc_context)) != 0)
213
goto badframe;
214
215
/* non-iBCS2 extensions.. */
216
if (__put_user(mask, &sc->sc_oldmask) < 0)
217
goto badframe;
218
219
return 0;
220
221
badframe:
222
return 1;
223
}
224
225
/*****************************************************************************/
226
/*
227
* Determine which stack to use..
228
*/
229
static inline void __user *get_sigframe(struct k_sigaction *ka,
230
size_t frame_size)
231
{
232
unsigned long sp;
233
234
/* Default to using normal stack */
235
sp = __frame->sp;
236
237
/* This is the X/Open sanctioned signal stack switching. */
238
if (ka->sa.sa_flags & SA_ONSTACK) {
239
if (! sas_ss_flags(sp))
240
sp = current->sas_ss_sp + current->sas_ss_size;
241
}
242
243
return (void __user *) ((sp - frame_size) & ~7UL);
244
245
} /* end get_sigframe() */
246
247
/*****************************************************************************/
248
/*
249
*
250
*/
251
static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
252
{
253
struct sigframe __user *frame;
254
int rsig;
255
256
set_fs(USER_DS);
257
258
frame = get_sigframe(ka, sizeof(*frame));
259
260
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
261
goto give_sigsegv;
262
263
rsig = sig;
264
if (sig < 32 &&
265
__current_thread_info->exec_domain &&
266
__current_thread_info->exec_domain->signal_invmap)
267
rsig = __current_thread_info->exec_domain->signal_invmap[sig];
268
269
if (__put_user(rsig, &frame->sig) < 0)
270
goto give_sigsegv;
271
272
if (setup_sigcontext(&frame->sc, set->sig[0]))
273
goto give_sigsegv;
274
275
if (_NSIG_WORDS > 1) {
276
if (__copy_to_user(frame->extramask, &set->sig[1],
277
sizeof(frame->extramask)))
278
goto give_sigsegv;
279
}
280
281
/* Set up to return from userspace. If provided, use a stub
282
* already in userspace. */
283
if (ka->sa.sa_flags & SA_RESTORER) {
284
if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0)
285
goto give_sigsegv;
286
}
287
else {
288
/* Set up the following code on the stack:
289
* setlos #__NR_sigreturn,gr7
290
* tira gr0,0
291
*/
292
if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
293
__put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
294
__put_user(0xc0700000, &frame->retcode[1]))
295
goto give_sigsegv;
296
297
flush_icache_range((unsigned long) frame->retcode,
298
(unsigned long) (frame->retcode + 2));
299
}
300
301
/* Set up registers for the signal handler */
302
if (current->personality & FDPIC_FUNCPTRS) {
303
struct fdpic_func_descriptor __user *funcptr =
304
(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
305
struct fdpic_func_descriptor desc;
306
if (copy_from_user(&desc, funcptr, sizeof(desc)))
307
goto give_sigsegv;
308
__frame->pc = desc.text;
309
__frame->gr15 = desc.GOT;
310
} else {
311
__frame->pc = (unsigned long) ka->sa.sa_handler;
312
__frame->gr15 = 0;
313
}
314
315
__frame->sp = (unsigned long) frame;
316
__frame->lr = (unsigned long) &frame->retcode;
317
__frame->gr8 = sig;
318
319
/* the tracer may want to single-step inside the handler */
320
if (test_thread_flag(TIF_SINGLESTEP))
321
ptrace_notify(SIGTRAP);
322
323
#if DEBUG_SIG
324
printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
325
sig, current->comm, current->pid, frame, __frame->pc,
326
frame->pretcode);
327
#endif
328
329
return 0;
330
331
give_sigsegv:
332
force_sigsegv(sig, current);
333
return -EFAULT;
334
335
} /* end setup_frame() */
336
337
/*****************************************************************************/
338
/*
339
*
340
*/
341
static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
342
sigset_t *set)
343
{
344
struct rt_sigframe __user *frame;
345
int rsig;
346
347
set_fs(USER_DS);
348
349
frame = get_sigframe(ka, sizeof(*frame));
350
351
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
352
goto give_sigsegv;
353
354
rsig = sig;
355
if (sig < 32 &&
356
__current_thread_info->exec_domain &&
357
__current_thread_info->exec_domain->signal_invmap)
358
rsig = __current_thread_info->exec_domain->signal_invmap[sig];
359
360
if (__put_user(rsig, &frame->sig) ||
361
__put_user(&frame->info, &frame->pinfo) ||
362
__put_user(&frame->uc, &frame->puc))
363
goto give_sigsegv;
364
365
if (copy_siginfo_to_user(&frame->info, info))
366
goto give_sigsegv;
367
368
/* Create the ucontext. */
369
if (__put_user(0, &frame->uc.uc_flags) ||
370
__put_user(NULL, &frame->uc.uc_link) ||
371
__put_user((void __user *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
372
__put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
373
__put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
374
goto give_sigsegv;
375
376
if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
377
goto give_sigsegv;
378
379
if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
380
goto give_sigsegv;
381
382
/* Set up to return from userspace. If provided, use a stub
383
* already in userspace. */
384
if (ka->sa.sa_flags & SA_RESTORER) {
385
if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
386
goto give_sigsegv;
387
}
388
else {
389
/* Set up the following code on the stack:
390
* setlos #__NR_sigreturn,gr7
391
* tira gr0,0
392
*/
393
if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
394
__put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
395
__put_user(0xc0700000, &frame->retcode[1]))
396
goto give_sigsegv;
397
398
flush_icache_range((unsigned long) frame->retcode,
399
(unsigned long) (frame->retcode + 2));
400
}
401
402
/* Set up registers for signal handler */
403
if (current->personality & FDPIC_FUNCPTRS) {
404
struct fdpic_func_descriptor __user *funcptr =
405
(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
406
struct fdpic_func_descriptor desc;
407
if (copy_from_user(&desc, funcptr, sizeof(desc)))
408
goto give_sigsegv;
409
__frame->pc = desc.text;
410
__frame->gr15 = desc.GOT;
411
} else {
412
__frame->pc = (unsigned long) ka->sa.sa_handler;
413
__frame->gr15 = 0;
414
}
415
416
__frame->sp = (unsigned long) frame;
417
__frame->lr = (unsigned long) &frame->retcode;
418
__frame->gr8 = sig;
419
__frame->gr9 = (unsigned long) &frame->info;
420
421
/* the tracer may want to single-step inside the handler */
422
if (test_thread_flag(TIF_SINGLESTEP))
423
ptrace_notify(SIGTRAP);
424
425
#if DEBUG_SIG
426
printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
427
sig, current->comm, current->pid, frame, __frame->pc,
428
frame->pretcode);
429
#endif
430
431
return 0;
432
433
give_sigsegv:
434
force_sigsegv(sig, current);
435
return -EFAULT;
436
437
} /* end setup_rt_frame() */
438
439
/*****************************************************************************/
440
/*
441
* OK, we're invoking a handler
442
*/
443
static int handle_signal(unsigned long sig, siginfo_t *info,
444
struct k_sigaction *ka, sigset_t *oldset)
445
{
446
int ret;
447
448
/* Are we from a system call? */
449
if (__frame->syscallno != -1) {
450
/* If so, check system call restarting.. */
451
switch (__frame->gr8) {
452
case -ERESTART_RESTARTBLOCK:
453
case -ERESTARTNOHAND:
454
__frame->gr8 = -EINTR;
455
break;
456
457
case -ERESTARTSYS:
458
if (!(ka->sa.sa_flags & SA_RESTART)) {
459
__frame->gr8 = -EINTR;
460
break;
461
}
462
463
/* fallthrough */
464
case -ERESTARTNOINTR:
465
__frame->gr8 = __frame->orig_gr8;
466
__frame->pc -= 4;
467
}
468
__frame->syscallno = -1;
469
}
470
471
/* Set up the stack frame */
472
if (ka->sa.sa_flags & SA_SIGINFO)
473
ret = setup_rt_frame(sig, ka, info, oldset);
474
else
475
ret = setup_frame(sig, ka, oldset);
476
477
if (ret == 0) {
478
spin_lock_irq(&current->sighand->siglock);
479
sigorsets(&current->blocked, &current->blocked,
480
&ka->sa.sa_mask);
481
if (!(ka->sa.sa_flags & SA_NODEFER))
482
sigaddset(&current->blocked, sig);
483
recalc_sigpending();
484
spin_unlock_irq(&current->sighand->siglock);
485
}
486
487
return ret;
488
489
} /* end handle_signal() */
490
491
/*****************************************************************************/
492
/*
493
* Note that 'init' is a special process: it doesn't get signals it doesn't
494
* want to handle. Thus you cannot kill init even with a SIGKILL even by
495
* mistake.
496
*/
497
static void do_signal(void)
498
{
499
struct k_sigaction ka;
500
siginfo_t info;
501
sigset_t *oldset;
502
int signr;
503
504
/*
505
* We want the common case to go fast, which
506
* is why we may in certain cases get here from
507
* kernel mode. Just return without doing anything
508
* if so.
509
*/
510
if (!user_mode(__frame))
511
return;
512
513
if (try_to_freeze())
514
goto no_signal;
515
516
if (test_thread_flag(TIF_RESTORE_SIGMASK))
517
oldset = &current->saved_sigmask;
518
else
519
oldset = &current->blocked;
520
521
signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
522
if (signr > 0) {
523
if (handle_signal(signr, &info, &ka, oldset) == 0) {
524
/* a signal was successfully delivered; the saved
525
* sigmask will have been stored in the signal frame,
526
* and will be restored by sigreturn, so we can simply
527
* clear the TIF_RESTORE_SIGMASK flag */
528
if (test_thread_flag(TIF_RESTORE_SIGMASK))
529
clear_thread_flag(TIF_RESTORE_SIGMASK);
530
531
tracehook_signal_handler(signr, &info, &ka, __frame,
532
test_thread_flag(TIF_SINGLESTEP));
533
}
534
535
return;
536
}
537
538
no_signal:
539
/* Did we come from a system call? */
540
if (__frame->syscallno != -1) {
541
/* Restart the system call - no handlers present */
542
switch (__frame->gr8) {
543
case -ERESTARTNOHAND:
544
case -ERESTARTSYS:
545
case -ERESTARTNOINTR:
546
__frame->gr8 = __frame->orig_gr8;
547
__frame->pc -= 4;
548
break;
549
550
case -ERESTART_RESTARTBLOCK:
551
__frame->gr7 = __NR_restart_syscall;
552
__frame->pc -= 4;
553
break;
554
}
555
__frame->syscallno = -1;
556
}
557
558
/* if there's no signal to deliver, we just put the saved sigmask
559
* back */
560
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
561
clear_thread_flag(TIF_RESTORE_SIGMASK);
562
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
563
}
564
565
} /* end do_signal() */
566
567
/*****************************************************************************/
568
/*
569
* notification of userspace execution resumption
570
* - triggered by the TIF_WORK_MASK flags
571
*/
572
asmlinkage void do_notify_resume(__u32 thread_info_flags)
573
{
574
/* pending single-step? */
575
if (thread_info_flags & _TIF_SINGLESTEP)
576
clear_thread_flag(TIF_SINGLESTEP);
577
578
/* deal with pending signal delivery */
579
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
580
do_signal();
581
582
/* deal with notification on about to resume userspace execution */
583
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
584
clear_thread_flag(TIF_NOTIFY_RESUME);
585
tracehook_notify_resume(__frame);
586
if (current->replacement_session_keyring)
587
key_replace_session_keyring();
588
}
589
590
} /* end do_notify_resume() */
591
592