1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/sched.h>
18#include <linux/sched/task_stack.h>
19#include <linux/mm.h>
20#include <linux/smp.h>
21#include <linux/kernel.h>
22#include <linux/signal.h>
23#include <linux/errno.h>
24#include <linux/wait.h>
25#include <linux/ptrace.h>
26#include <linux/unistd.h>
27#include <linux/stddef.h>
28
29#include <asm/processor.h>
30#include <asm/ucontext.h>
31#include <linux/uaccess.h>
32#include <arch/system.h>
33
34#define DEBUG_SIG 0
35
36
37
38
39
40
41
42#define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2;
43
44void do_signal(int canrestart, struct pt_regs *regs);
45
46
47
48
49
50struct sigframe {
51 struct sigcontext sc;
52 unsigned long extramask[_NSIG_WORDS-1];
53 unsigned char retcode[8];
54};
55
56struct rt_sigframe {
57 struct siginfo *pinfo;
58 void *puc;
59 struct siginfo info;
60 struct ucontext uc;
61 unsigned char retcode[8];
62};
63
64
65static int
66restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
67{
68 unsigned int err = 0;
69 unsigned long old_usp;
70
71
72 current->restart_block.fn = do_no_restart_syscall;
73
74
75
76
77
78
79 if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
80 goto badframe;
81
82
83
84 regs->dccr |= 1 << 8;
85
86
87
88
89
90
91 err |= __get_user(old_usp, &sc->usp);
92
93 wrusp(old_usp);
94
95
96
97
98
99
100 return err;
101
102badframe:
103 return 1;
104}
105
106asmlinkage int sys_sigreturn(void)
107{
108 struct pt_regs *regs = current_pt_regs();
109 struct sigframe __user *frame = (struct sigframe *)rdusp();
110 sigset_t set;
111
112
113
114
115
116
117 if (((long)frame) & 3)
118 goto badframe;
119
120 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
121 goto badframe;
122 if (__get_user(set.sig[0], &frame->sc.oldmask)
123 || (_NSIG_WORDS > 1
124 && __copy_from_user(&set.sig[1], frame->extramask,
125 sizeof(frame->extramask))))
126 goto badframe;
127
128 set_current_blocked(&set);
129
130 if (restore_sigcontext(regs, &frame->sc))
131 goto badframe;
132
133
134
135 return regs->r10;
136
137badframe:
138 force_sig(SIGSEGV, current);
139 return 0;
140}
141
142asmlinkage int sys_rt_sigreturn(void)
143{
144 struct pt_regs *regs = current_pt_regs();
145 struct rt_sigframe __user *frame = (struct rt_sigframe *)rdusp();
146 sigset_t set;
147
148
149
150
151
152
153 if (((long)frame) & 3)
154 goto badframe;
155
156 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
157 goto badframe;
158 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
159 goto badframe;
160
161 set_current_blocked(&set);
162
163 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
164 goto badframe;
165
166 if (restore_altstack(&frame->uc.uc_stack))
167 goto badframe;
168
169 return regs->r10;
170
171badframe:
172 force_sig(SIGSEGV, current);
173 return 0;
174}
175
176
177
178
179
180static int setup_sigcontext(struct sigcontext __user *sc,
181 struct pt_regs *regs, unsigned long mask)
182{
183 int err = 0;
184 unsigned long usp = rdusp();
185
186
187
188 err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
189
190
191
192
193 regs->frametype = CRIS_FRAME_NORMAL;
194
195
196
197 err |= __put_user(mask, &sc->oldmask);
198
199 err |= __put_user(usp, &sc->usp);
200
201 return err;
202}
203
204
205
206
207static inline void __user *
208get_sigframe(struct ksignal *ksig, size_t frame_size)
209{
210 unsigned long sp = sigsp(rdusp(), ksig);
211
212
213
214 sp &= ~3;
215
216 return (void __user*)(sp - frame_size);
217}
218
219
220
221
222
223
224
225
226
227static int setup_frame(struct ksignal *ksig, sigset_t *set,
228 struct pt_regs *regs)
229{
230 struct sigframe __user *frame;
231 unsigned long return_ip;
232 int err = 0;
233
234 frame = get_sigframe(ksig, sizeof(*frame));
235
236 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
237 return -EFAULT;
238
239 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
240 if (err)
241 return -EFAULT;
242
243 if (_NSIG_WORDS > 1) {
244 err |= __copy_to_user(frame->extramask, &set->sig[1],
245 sizeof(frame->extramask));
246 }
247 if (err)
248 return -EFAULT;
249
250
251
252 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
253 return_ip = (unsigned long)ksig->ka.sa.sa_restorer;
254 } else {
255
256 return_ip = (unsigned long)&frame->retcode;
257
258 err |= __put_user(0x9c5f, (short __user*)(frame->retcode+0));
259 err |= __put_user(__NR_sigreturn, (short __user*)(frame->retcode+2));
260 err |= __put_user(0xe93d, (short __user*)(frame->retcode+4));
261 }
262
263 if (err)
264 return -EFAULT;
265
266
267
268 regs->irp = (unsigned long) ksig->ka.sa.sa_handler;
269 regs->srp = return_ip;
270 regs->r10 = ksig->sig;
271
272
273
274 wrusp((unsigned long)frame);
275
276 return 0;
277}
278
279static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
280 struct pt_regs *regs)
281{
282 struct rt_sigframe __user *frame;
283 unsigned long return_ip;
284 int err = 0;
285
286 frame = get_sigframe(ksig, sizeof(*frame));
287
288 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
289 return -EFAULT;
290
291 err |= __put_user(&frame->info, &frame->pinfo);
292 err |= __put_user(&frame->uc, &frame->puc);
293 err |= copy_siginfo_to_user(&frame->info, &ksig->info);
294 if (err)
295 return -EFAULT;
296
297
298 err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
299
300 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
301
302 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
303
304 err |= __save_altstack(&frame->uc.uc_stack, rdusp());
305
306 if (err)
307 return -EFAULT;
308
309
310
311 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
312 return_ip = (unsigned long)ksig->ka.sa.sa_restorer;
313 } else {
314
315 return_ip = (unsigned long)&frame->retcode;
316
317 err |= __put_user(0x9c5f, (short __user *)(frame->retcode+0));
318 err |= __put_user(__NR_rt_sigreturn,
319 (short __user *)(frame->retcode+2));
320 err |= __put_user(0xe93d, (short __user *)(frame->retcode+4));
321 }
322
323 if (err)
324 return -EFAULT;
325
326
327
328
329 regs->irp = (unsigned long) ksig->ka.sa.sa_handler;
330
331 regs->srp = return_ip;
332
333 regs->r10 = ksig->sig;
334
335 regs->r11 = (unsigned long)&frame->info;
336
337 regs->r12 = 0;
338
339
340 wrusp((unsigned long)frame);
341
342 return 0;
343}
344
345
346
347
348
349static inline void handle_signal(int canrestart, struct ksignal *ksig,
350 struct pt_regs *regs)
351{
352 sigset_t *oldset = sigmask_to_save();
353 int ret;
354
355
356 if (canrestart) {
357
358 switch (regs->r10) {
359 case -ERESTART_RESTARTBLOCK:
360 case -ERESTARTNOHAND:
361
362
363
364
365 regs->r10 = -EINTR;
366 break;
367 case -ERESTARTSYS:
368
369
370
371 if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
372 regs->r10 = -EINTR;
373 break;
374 }
375
376 case -ERESTARTNOINTR:
377
378
379 RESTART_CRIS_SYS(regs);
380 }
381 }
382
383
384 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
385 ret = setup_rt_frame(ksig, oldset, regs);
386 else
387 ret = setup_frame(ksig, oldset, regs);
388
389 signal_setup_done(ret, ksig, 0);
390}
391
392
393
394
395
396
397
398
399
400
401
402
403
404void do_signal(int canrestart, struct pt_regs *regs)
405{
406 struct ksignal ksig;
407
408
409
410
411
412
413
414 if (!user_mode(regs))
415 return;
416
417 if (get_signal(&ksig)) {
418
419 handle_signal(canrestart, &ksig, regs);
420 return;
421 }
422
423
424 if (canrestart) {
425
426 if (regs->r10 == -ERESTARTNOHAND ||
427 regs->r10 == -ERESTARTSYS ||
428 regs->r10 == -ERESTARTNOINTR) {
429 RESTART_CRIS_SYS(regs);
430 }
431 if (regs->r10 == -ERESTART_RESTARTBLOCK) {
432 regs->r9 = __NR_restart_syscall;
433 regs->irp -= 2;
434 }
435 }
436
437
438
439 restore_saved_sigmask();
440}
441