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