1
2
3
4
5
6
7
8
9
10
11
12#include <linux/sched.h>
13#include <linux/mm.h>
14#include <linux/smp.h>
15#include <linux/kernel.h>
16#include <linux/signal.h>
17#include <linux/errno.h>
18#include <linux/wait.h>
19#include <linux/ptrace.h>
20#include <linux/unistd.h>
21#include <linux/stddef.h>
22#include <linux/tty.h>
23#include <linux/personality.h>
24#include <linux/binfmts.h>
25#include <linux/tracehook.h>
26#include <linux/syscalls.h>
27#include <linux/compat.h>
28#include <asm/ucontext.h>
29#include <asm/uaccess.h>
30#include <asm/lowcore.h>
31#include <asm/switch_to.h>
32#include "entry.h"
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61struct sigframe
62{
63 __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
64 struct sigcontext sc;
65 _sigregs sregs;
66 int signo;
67 _sigregs_ext sregs_ext;
68 __u16 svc_insn;
69};
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96struct rt_sigframe
97{
98 __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
99 __u16 svc_insn;
100 struct siginfo info;
101 struct ucontext_extended uc;
102};
103
104
105static void store_sigregs(void)
106{
107 save_access_regs(current->thread.acrs);
108 save_fp_ctl(¤t->thread.fp_regs.fpc);
109#ifdef CONFIG_64BIT
110 if (current->thread.vxrs) {
111 int i;
112
113 save_vx_regs(current->thread.vxrs);
114 for (i = 0; i < __NUM_FPRS; i++)
115 current->thread.fp_regs.fprs[i] =
116 *(freg_t *)(current->thread.vxrs + i);
117 } else
118#endif
119 save_fp_regs(current->thread.fp_regs.fprs);
120}
121
122
123static void load_sigregs(void)
124{
125 restore_access_regs(current->thread.acrs);
126
127#ifdef CONFIG_64BIT
128 if (current->thread.vxrs) {
129 int i;
130
131 for (i = 0; i < __NUM_FPRS; i++)
132 *(freg_t *)(current->thread.vxrs + i) =
133 current->thread.fp_regs.fprs[i];
134 restore_vx_regs(current->thread.vxrs);
135 } else
136#endif
137 restore_fp_regs(current->thread.fp_regs.fprs);
138}
139
140
141static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
142{
143 _sigregs user_sregs;
144
145
146
147 user_sregs.regs.psw.mask = PSW_USER_BITS |
148 (regs->psw.mask & (PSW_MASK_USER | PSW_MASK_RI));
149 user_sregs.regs.psw.addr = regs->psw.addr;
150 memcpy(&user_sregs.regs.gprs, ®s->gprs, sizeof(sregs->regs.gprs));
151 memcpy(&user_sregs.regs.acrs, current->thread.acrs,
152 sizeof(user_sregs.regs.acrs));
153 memcpy(&user_sregs.fpregs, ¤t->thread.fp_regs,
154 sizeof(user_sregs.fpregs));
155 if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs)))
156 return -EFAULT;
157 return 0;
158}
159
160static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
161{
162 _sigregs user_sregs;
163
164
165 current_thread_info()->restart_block.fn = do_no_restart_syscall;
166
167 if (__copy_from_user(&user_sregs, sregs, sizeof(user_sregs)))
168 return -EFAULT;
169
170 if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW_MASK_RI))
171 return -EINVAL;
172
173
174 if (restore_fp_ctl(&user_sregs.fpregs.fpc))
175 return -EINVAL;
176
177
178 regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
179 (user_sregs.regs.psw.mask & (PSW_MASK_USER | PSW_MASK_RI));
180
181 if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
182 regs->psw.mask = PSW_ASC_PRIMARY |
183 (regs->psw.mask & ~PSW_MASK_ASC);
184
185 if (regs->psw.mask & PSW_MASK_EA)
186 regs->psw.mask |= PSW_MASK_BA;
187 regs->psw.addr = user_sregs.regs.psw.addr;
188 memcpy(®s->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs));
189 memcpy(¤t->thread.acrs, &user_sregs.regs.acrs,
190 sizeof(current->thread.acrs));
191
192 memcpy(¤t->thread.fp_regs, &user_sregs.fpregs,
193 sizeof(current->thread.fp_regs));
194
195 clear_thread_flag(TIF_SYSCALL);
196 return 0;
197}
198
199
200static int save_sigregs_ext(struct pt_regs *regs,
201 _sigregs_ext __user *sregs_ext)
202{
203#ifdef CONFIG_64BIT
204 __u64 vxrs[__NUM_VXRS_LOW];
205 int i;
206
207
208 if (current->thread.vxrs) {
209 for (i = 0; i < __NUM_VXRS_LOW; i++)
210 vxrs[i] = *((__u64 *)(current->thread.vxrs + i) + 1);
211 if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,
212 sizeof(sregs_ext->vxrs_low)) ||
213 __copy_to_user(&sregs_ext->vxrs_high,
214 current->thread.vxrs + __NUM_VXRS_LOW,
215 sizeof(sregs_ext->vxrs_high)))
216 return -EFAULT;
217 }
218#endif
219 return 0;
220}
221
222static int restore_sigregs_ext(struct pt_regs *regs,
223 _sigregs_ext __user *sregs_ext)
224{
225#ifdef CONFIG_64BIT
226 __u64 vxrs[__NUM_VXRS_LOW];
227 int i;
228
229
230 if (current->thread.vxrs) {
231 if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,
232 sizeof(sregs_ext->vxrs_low)) ||
233 __copy_from_user(current->thread.vxrs + __NUM_VXRS_LOW,
234 &sregs_ext->vxrs_high,
235 sizeof(sregs_ext->vxrs_high)))
236 return -EFAULT;
237 for (i = 0; i < __NUM_VXRS_LOW; i++)
238 *((__u64 *)(current->thread.vxrs + i) + 1) = vxrs[i];
239 }
240#endif
241 return 0;
242}
243
244SYSCALL_DEFINE0(sigreturn)
245{
246 struct pt_regs *regs = task_pt_regs(current);
247 struct sigframe __user *frame =
248 (struct sigframe __user *) regs->gprs[15];
249 sigset_t set;
250
251 if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
252 goto badframe;
253 set_current_blocked(&set);
254 if (restore_sigregs(regs, &frame->sregs))
255 goto badframe;
256 if (restore_sigregs_ext(regs, &frame->sregs_ext))
257 goto badframe;
258 load_sigregs();
259 return regs->gprs[2];
260badframe:
261 force_sig(SIGSEGV, current);
262 return 0;
263}
264
265SYSCALL_DEFINE0(rt_sigreturn)
266{
267 struct pt_regs *regs = task_pt_regs(current);
268 struct rt_sigframe __user *frame =
269 (struct rt_sigframe __user *)regs->gprs[15];
270 sigset_t set;
271
272 if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set)))
273 goto badframe;
274 set_current_blocked(&set);
275 if (restore_altstack(&frame->uc.uc_stack))
276 goto badframe;
277 if (restore_sigregs(regs, &frame->uc.uc_mcontext))
278 goto badframe;
279 if (restore_sigregs_ext(regs, &frame->uc.uc_mcontext_ext))
280 goto badframe;
281 load_sigregs();
282 return regs->gprs[2];
283badframe:
284 force_sig(SIGSEGV, current);
285 return 0;
286}
287
288
289
290
291static inline void __user *
292get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
293{
294 unsigned long sp;
295
296
297 sp = regs->gprs[15];
298
299
300 if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL))
301 return (void __user *) -1UL;
302
303
304 if (ka->sa.sa_flags & SA_ONSTACK) {
305 if (! sas_ss_flags(sp))
306 sp = current->sas_ss_sp + current->sas_ss_size;
307 }
308
309 return (void __user *)((sp - frame_size) & -8ul);
310}
311
312static inline int map_signal(int sig)
313{
314 if (current_thread_info()->exec_domain
315 && current_thread_info()->exec_domain->signal_invmap
316 && sig < 32)
317 return current_thread_info()->exec_domain->signal_invmap[sig];
318 else
319 return sig;
320}
321
322static int setup_frame(int sig, struct k_sigaction *ka,
323 sigset_t *set, struct pt_regs * regs)
324{
325 struct sigframe __user *frame;
326 struct sigcontext sc;
327 unsigned long restorer;
328 size_t frame_size;
329
330
331
332
333
334
335
336 frame_size = sizeof(*frame) - sizeof(frame->sregs_ext);
337 if (MACHINE_HAS_VX)
338 frame_size += sizeof(frame->sregs_ext);
339 frame = get_sigframe(ka, regs, frame_size);
340 if (frame == (void __user *) -1UL)
341 goto give_sigsegv;
342
343
344 if (__put_user(regs->gprs[15], (addr_t __user *) frame))
345 goto give_sigsegv;
346
347
348 memcpy(&sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE);
349 sc.sregs = (_sigregs __user __force *) &frame->sregs;
350 if (__copy_to_user(&frame->sc, &sc, sizeof(frame->sc)))
351 goto give_sigsegv;
352
353
354 store_sigregs();
355
356
357 if (save_sigregs(regs, &frame->sregs))
358 goto give_sigsegv;
359
360
361 if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
362 goto give_sigsegv;
363
364
365 if (save_sigregs_ext(regs, &frame->sregs_ext))
366 goto give_sigsegv;
367
368
369
370 if (ka->sa.sa_flags & SA_RESTORER) {
371 restorer = (unsigned long) ka->sa.sa_restorer | PSW_ADDR_AMODE;
372 } else {
373
374 __u16 __user *svc = (void *) frame + frame_size - 2;
375 if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc))
376 goto give_sigsegv;
377 restorer = (unsigned long) svc | PSW_ADDR_AMODE;
378 }
379
380
381 regs->gprs[14] = restorer;
382 regs->gprs[15] = (unsigned long) frame;
383
384 regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
385 (PSW_USER_BITS & PSW_MASK_ASC) |
386 (regs->psw.mask & ~PSW_MASK_ASC);
387 regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
388
389 regs->gprs[2] = map_signal(sig);
390 regs->gprs[3] = (unsigned long) &frame->sc;
391
392
393
394 if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
395 sig == SIGTRAP || sig == SIGFPE) {
396
397 regs->gprs[4] = regs->int_code & 127;
398 regs->gprs[5] = regs->int_parm_long;
399 regs->gprs[6] = task_thread_info(current)->last_break;
400 }
401 return 0;
402
403give_sigsegv:
404 force_sigsegv(sig, current);
405 return -EFAULT;
406}
407
408static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
409 sigset_t *set, struct pt_regs * regs)
410{
411 struct rt_sigframe __user *frame;
412 unsigned long uc_flags, restorer;
413 size_t frame_size;
414
415 frame_size = sizeof(struct rt_sigframe) - sizeof(_sigregs_ext);
416
417
418
419
420
421
422 uc_flags = 0;
423#ifdef CONFIG_64BIT
424 if (MACHINE_HAS_VX) {
425 frame_size += sizeof(_sigregs_ext);
426 if (current->thread.vxrs)
427 uc_flags |= UC_VXRS;
428 }
429#endif
430 frame = get_sigframe(ka, regs, frame_size);
431 if (frame == (void __user *) -1UL)
432 goto give_sigsegv;
433
434
435 if (__put_user(regs->gprs[15], (addr_t __user *) frame))
436 goto give_sigsegv;
437
438
439
440 if (ka->sa.sa_flags & SA_RESTORER) {
441 restorer = (unsigned long)
442 ka->sa.sa_restorer | PSW_ADDR_AMODE;
443 } else {
444 __u16 __user *svc = &frame->svc_insn;
445 if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc))
446 goto give_sigsegv;
447 restorer = (unsigned long) svc | PSW_ADDR_AMODE;
448 }
449
450
451 if (copy_siginfo_to_user(&frame->info, info))
452 goto give_sigsegv;
453
454
455 store_sigregs();
456
457
458 if (__put_user(uc_flags, &frame->uc.uc_flags) ||
459 __put_user(NULL, &frame->uc.uc_link) ||
460 __save_altstack(&frame->uc.uc_stack, regs->gprs[15]) ||
461 save_sigregs(regs, &frame->uc.uc_mcontext) ||
462 __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)) ||
463 save_sigregs_ext(regs, &frame->uc.uc_mcontext_ext))
464 goto give_sigsegv;
465
466
467 regs->gprs[14] = restorer;
468 regs->gprs[15] = (unsigned long) frame;
469
470 regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
471 (PSW_USER_BITS & PSW_MASK_ASC) |
472 (regs->psw.mask & ~PSW_MASK_ASC);
473 regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
474
475 regs->gprs[2] = map_signal(sig);
476 regs->gprs[3] = (unsigned long) &frame->info;
477 regs->gprs[4] = (unsigned long) &frame->uc;
478 regs->gprs[5] = task_thread_info(current)->last_break;
479 return 0;
480
481give_sigsegv:
482 force_sigsegv(sig, current);
483 return -EFAULT;
484}
485
486static void handle_signal(unsigned long sig, struct k_sigaction *ka,
487 siginfo_t *info, sigset_t *oldset,
488 struct pt_regs *regs)
489{
490 int ret;
491
492
493 if (ka->sa.sa_flags & SA_SIGINFO)
494 ret = setup_rt_frame(sig, ka, info, oldset, regs);
495 else
496 ret = setup_frame(sig, ka, oldset, regs);
497 if (ret)
498 return;
499 signal_delivered(sig, info, ka, regs,
500 test_thread_flag(TIF_SINGLE_STEP));
501}
502
503
504
505
506
507
508
509
510
511
512void do_signal(struct pt_regs *regs)
513{
514 siginfo_t info;
515 int signr;
516 struct k_sigaction ka;
517 sigset_t *oldset = sigmask_to_save();
518
519
520
521
522
523
524 current_thread_info()->system_call =
525 test_thread_flag(TIF_SYSCALL) ? regs->int_code : 0;
526 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
527
528 if (signr > 0) {
529
530 if (current_thread_info()->system_call) {
531 regs->int_code = current_thread_info()->system_call;
532
533 switch (regs->gprs[2]) {
534 case -ERESTART_RESTARTBLOCK:
535 case -ERESTARTNOHAND:
536 regs->gprs[2] = -EINTR;
537 break;
538 case -ERESTARTSYS:
539 if (!(ka.sa.sa_flags & SA_RESTART)) {
540 regs->gprs[2] = -EINTR;
541 break;
542 }
543
544 case -ERESTARTNOINTR:
545 regs->gprs[2] = regs->orig_gpr2;
546 regs->psw.addr =
547 __rewind_psw(regs->psw,
548 regs->int_code >> 16);
549 break;
550 }
551 }
552
553 clear_thread_flag(TIF_SYSCALL);
554
555 if (is_compat_task())
556 handle_signal32(signr, &ka, &info, oldset, regs);
557 else
558 handle_signal(signr, &ka, &info, oldset, regs);
559 return;
560 }
561
562
563 clear_thread_flag(TIF_SYSCALL);
564 if (current_thread_info()->system_call) {
565 regs->int_code = current_thread_info()->system_call;
566 switch (regs->gprs[2]) {
567 case -ERESTART_RESTARTBLOCK:
568
569 regs->int_code = __NR_restart_syscall;
570
571 case -ERESTARTNOHAND:
572 case -ERESTARTSYS:
573 case -ERESTARTNOINTR:
574
575 regs->gprs[2] = regs->orig_gpr2;
576 set_thread_flag(TIF_SYSCALL);
577 if (test_thread_flag(TIF_SINGLE_STEP))
578 set_thread_flag(TIF_PER_TRAP);
579 break;
580 }
581 }
582
583
584
585
586 restore_saved_sigmask();
587}
588
589void do_notify_resume(struct pt_regs *regs)
590{
591 clear_thread_flag(TIF_NOTIFY_RESUME);
592 tracehook_notify_resume(regs);
593}
594