Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/blackfin/kernel/signal.c
10817 views
1
/*
2
* Copyright 2004-2010 Analog Devices Inc.
3
*
4
* Licensed under the GPL-2 or later
5
*/
6
7
#include <linux/signal.h>
8
#include <linux/syscalls.h>
9
#include <linux/ptrace.h>
10
#include <linux/tty.h>
11
#include <linux/personality.h>
12
#include <linux/binfmts.h>
13
#include <linux/freezer.h>
14
#include <linux/uaccess.h>
15
#include <linux/tracehook.h>
16
17
#include <asm/cacheflush.h>
18
#include <asm/ucontext.h>
19
#include <asm/fixed_code.h>
20
#include <asm/syscall.h>
21
22
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
23
24
/* Location of the trace bit in SYSCFG. */
25
#define TRACE_BITS 0x0001
26
27
struct fdpic_func_descriptor {
28
unsigned long text;
29
unsigned long GOT;
30
};
31
32
struct rt_sigframe {
33
int sig;
34
struct siginfo *pinfo;
35
void *puc;
36
/* This is no longer needed by the kernel, but unfortunately userspace
37
* code expects it to be there. */
38
char retcode[8];
39
struct siginfo info;
40
struct ucontext uc;
41
};
42
43
asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
44
{
45
return do_sigaltstack(uss, uoss, rdusp());
46
}
47
48
static inline int
49
rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *pr0)
50
{
51
unsigned long usp = 0;
52
int err = 0;
53
54
/* Always make any pending restarted system calls return -EINTR */
55
current_thread_info()->restart_block.fn = do_no_restart_syscall;
56
57
#define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x)
58
59
/* restore passed registers */
60
RESTORE(r0); RESTORE(r1); RESTORE(r2); RESTORE(r3);
61
RESTORE(r4); RESTORE(r5); RESTORE(r6); RESTORE(r7);
62
RESTORE(p0); RESTORE(p1); RESTORE(p2); RESTORE(p3);
63
RESTORE(p4); RESTORE(p5);
64
err |= __get_user(usp, &sc->sc_usp);
65
wrusp(usp);
66
RESTORE(a0w); RESTORE(a1w);
67
RESTORE(a0x); RESTORE(a1x);
68
RESTORE(astat);
69
RESTORE(rets);
70
RESTORE(pc);
71
RESTORE(retx);
72
RESTORE(fp);
73
RESTORE(i0); RESTORE(i1); RESTORE(i2); RESTORE(i3);
74
RESTORE(m0); RESTORE(m1); RESTORE(m2); RESTORE(m3);
75
RESTORE(l0); RESTORE(l1); RESTORE(l2); RESTORE(l3);
76
RESTORE(b0); RESTORE(b1); RESTORE(b2); RESTORE(b3);
77
RESTORE(lc0); RESTORE(lc1);
78
RESTORE(lt0); RESTORE(lt1);
79
RESTORE(lb0); RESTORE(lb1);
80
RESTORE(seqstat);
81
82
regs->orig_p0 = -1; /* disable syscall checks */
83
84
*pr0 = regs->r0;
85
return err;
86
}
87
88
asmlinkage int do_rt_sigreturn(unsigned long __unused)
89
{
90
struct pt_regs *regs = (struct pt_regs *)__unused;
91
unsigned long usp = rdusp();
92
struct rt_sigframe *frame = (struct rt_sigframe *)(usp);
93
sigset_t set;
94
int r0;
95
96
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
97
goto badframe;
98
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
99
goto badframe;
100
101
sigdelsetmask(&set, ~_BLOCKABLE);
102
spin_lock_irq(&current->sighand->siglock);
103
current->blocked = set;
104
recalc_sigpending();
105
spin_unlock_irq(&current->sighand->siglock);
106
107
if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
108
goto badframe;
109
110
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->usp) == -EFAULT)
111
goto badframe;
112
113
return r0;
114
115
badframe:
116
force_sig(SIGSEGV, current);
117
return 0;
118
}
119
120
static inline int rt_setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs)
121
{
122
int err = 0;
123
124
#define SETUP(x) err |= __put_user(regs->x, &sc->sc_##x)
125
126
SETUP(r0); SETUP(r1); SETUP(r2); SETUP(r3);
127
SETUP(r4); SETUP(r5); SETUP(r6); SETUP(r7);
128
SETUP(p0); SETUP(p1); SETUP(p2); SETUP(p3);
129
SETUP(p4); SETUP(p5);
130
err |= __put_user(rdusp(), &sc->sc_usp);
131
SETUP(a0w); SETUP(a1w);
132
SETUP(a0x); SETUP(a1x);
133
SETUP(astat);
134
SETUP(rets);
135
SETUP(pc);
136
SETUP(retx);
137
SETUP(fp);
138
SETUP(i0); SETUP(i1); SETUP(i2); SETUP(i3);
139
SETUP(m0); SETUP(m1); SETUP(m2); SETUP(m3);
140
SETUP(l0); SETUP(l1); SETUP(l2); SETUP(l3);
141
SETUP(b0); SETUP(b1); SETUP(b2); SETUP(b3);
142
SETUP(lc0); SETUP(lc1);
143
SETUP(lt0); SETUP(lt1);
144
SETUP(lb0); SETUP(lb1);
145
SETUP(seqstat);
146
147
return err;
148
}
149
150
static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
151
size_t frame_size)
152
{
153
unsigned long usp;
154
155
/* Default to using normal stack. */
156
usp = rdusp();
157
158
/* This is the X/Open sanctioned signal stack switching. */
159
if (ka->sa.sa_flags & SA_ONSTACK) {
160
if (!on_sig_stack(usp))
161
usp = current->sas_ss_sp + current->sas_ss_size;
162
}
163
return (void *)((usp - frame_size) & -8UL);
164
}
165
166
static int
167
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
168
sigset_t * set, struct pt_regs *regs)
169
{
170
struct rt_sigframe *frame;
171
int err = 0;
172
173
frame = get_sigframe(ka, regs, sizeof(*frame));
174
175
err |= __put_user((current_thread_info()->exec_domain
176
&& current_thread_info()->exec_domain->signal_invmap
177
&& sig < 32
178
? current_thread_info()->exec_domain->
179
signal_invmap[sig] : sig), &frame->sig);
180
181
err |= __put_user(&frame->info, &frame->pinfo);
182
err |= __put_user(&frame->uc, &frame->puc);
183
err |= copy_siginfo_to_user(&frame->info, info);
184
185
/* Create the ucontext. */
186
err |= __put_user(0, &frame->uc.uc_flags);
187
err |= __put_user(0, &frame->uc.uc_link);
188
err |=
189
__put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
190
err |= __put_user(sas_ss_flags(rdusp()), &frame->uc.uc_stack.ss_flags);
191
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
192
err |= rt_setup_sigcontext(&frame->uc.uc_mcontext, regs);
193
err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
194
195
if (err)
196
goto give_sigsegv;
197
198
/* Set up registers for signal handler */
199
wrusp((unsigned long)frame);
200
if (current->personality & FDPIC_FUNCPTRS) {
201
struct fdpic_func_descriptor __user *funcptr =
202
(struct fdpic_func_descriptor *) ka->sa.sa_handler;
203
__get_user(regs->pc, &funcptr->text);
204
__get_user(regs->p3, &funcptr->GOT);
205
} else
206
regs->pc = (unsigned long)ka->sa.sa_handler;
207
regs->rets = SIGRETURN_STUB;
208
209
regs->r0 = frame->sig;
210
regs->r1 = (unsigned long)(&frame->info);
211
regs->r2 = (unsigned long)(&frame->uc);
212
213
return 0;
214
215
give_sigsegv:
216
if (sig == SIGSEGV)
217
ka->sa.sa_handler = SIG_DFL;
218
force_sig(SIGSEGV, current);
219
return -EFAULT;
220
}
221
222
static inline void
223
handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
224
{
225
switch (regs->r0) {
226
case -ERESTARTNOHAND:
227
if (!has_handler)
228
goto do_restart;
229
regs->r0 = -EINTR;
230
break;
231
232
case -ERESTARTSYS:
233
if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
234
regs->r0 = -EINTR;
235
break;
236
}
237
/* fallthrough */
238
case -ERESTARTNOINTR:
239
do_restart:
240
regs->p0 = regs->orig_p0;
241
regs->r0 = regs->orig_r0;
242
regs->pc -= 2;
243
break;
244
245
case -ERESTART_RESTARTBLOCK:
246
regs->p0 = __NR_restart_syscall;
247
regs->pc -= 2;
248
break;
249
}
250
}
251
252
/*
253
* OK, we're invoking a handler
254
*/
255
static int
256
handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
257
sigset_t *oldset, struct pt_regs *regs)
258
{
259
int ret;
260
261
/* are we from a system call? to see pt_regs->orig_p0 */
262
if (regs->orig_p0 >= 0)
263
/* If so, check system call restarting.. */
264
handle_restart(regs, ka, 1);
265
266
/* set up the stack frame */
267
ret = setup_rt_frame(sig, ka, info, oldset, regs);
268
269
if (ret == 0) {
270
spin_lock_irq(&current->sighand->siglock);
271
sigorsets(&current->blocked, &current->blocked,
272
&ka->sa.sa_mask);
273
if (!(ka->sa.sa_flags & SA_NODEFER))
274
sigaddset(&current->blocked, sig);
275
recalc_sigpending();
276
spin_unlock_irq(&current->sighand->siglock);
277
}
278
return ret;
279
}
280
281
/*
282
* Note that 'init' is a special process: it doesn't get signals it doesn't
283
* want to handle. Thus you cannot kill init even with a SIGKILL even by
284
* mistake.
285
*
286
* Note that we go through the signals twice: once to check the signals
287
* that the kernel can handle, and then we build all the user-level signal
288
* handling stack-frames in one go after that.
289
*/
290
asmlinkage void do_signal(struct pt_regs *regs)
291
{
292
siginfo_t info;
293
int signr;
294
struct k_sigaction ka;
295
sigset_t *oldset;
296
297
current->thread.esp0 = (unsigned long)regs;
298
299
if (try_to_freeze())
300
goto no_signal;
301
302
if (test_thread_flag(TIF_RESTORE_SIGMASK))
303
oldset = &current->saved_sigmask;
304
else
305
oldset = &current->blocked;
306
307
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
308
if (signr > 0) {
309
/* Whee! Actually deliver the signal. */
310
if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
311
/* a signal was successfully delivered; the saved
312
* sigmask will have been stored in the signal frame,
313
* and will be restored by sigreturn, so we can simply
314
* clear the TIF_RESTORE_SIGMASK flag */
315
if (test_thread_flag(TIF_RESTORE_SIGMASK))
316
clear_thread_flag(TIF_RESTORE_SIGMASK);
317
318
tracehook_signal_handler(signr, &info, &ka, regs,
319
test_thread_flag(TIF_SINGLESTEP));
320
}
321
322
return;
323
}
324
325
no_signal:
326
/* Did we come from a system call? */
327
if (regs->orig_p0 >= 0)
328
/* Restart the system call - no handlers present */
329
handle_restart(regs, NULL, 0);
330
331
/* if there's no signal to deliver, we just put the saved sigmask
332
* back */
333
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
334
clear_thread_flag(TIF_RESTORE_SIGMASK);
335
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
336
}
337
}
338
339
/*
340
* notification of userspace execution resumption
341
*/
342
asmlinkage void do_notify_resume(struct pt_regs *regs)
343
{
344
if (test_thread_flag(TIF_SIGPENDING) || test_thread_flag(TIF_RESTORE_SIGMASK))
345
do_signal(regs);
346
347
if (test_thread_flag(TIF_NOTIFY_RESUME)) {
348
clear_thread_flag(TIF_NOTIFY_RESUME);
349
tracehook_notify_resume(regs);
350
if (current->replacement_session_keyring)
351
key_replace_session_keyring();
352
}
353
}
354
355
356