aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/compat_signal.c
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2014-07-13 16:21:03 -0400
committerRichard Weinberger <richard@sigma-star.at>2014-08-06 07:03:10 -0400
commit067bf2d4d3a7aedc5982f6a58716054e5004b801 (patch)
tree469ad85dced4694eb48344a36ce8706022332b87 /arch/s390/kernel/compat_signal.c
parent129b69df9c9074750245fca8aa92df5cc1a86ef4 (diff)
s390: Use get_signal() signal_setup_done()
Use the more generic functions get_signal() signal_setup_done() for signal delivery. Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/s390/kernel/compat_signal.c')
-rw-r--r--arch/s390/kernel/compat_signal.c79
1 files changed, 35 insertions, 44 deletions
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index f204d6920368..598b0b42668b 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -320,38 +320,39 @@ static inline int map_signal(int sig)
320 return sig; 320 return sig;
321} 321}
322 322
323static int setup_frame32(int sig, struct k_sigaction *ka, 323static int setup_frame32(struct ksignal *ksig, sigset_t *set,
324 sigset_t *set, struct pt_regs * regs) 324 struct pt_regs *regs)
325{ 325{
326 sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32)); 326 int sig = ksig->sig;
327 sigframe32 __user *frame = get_sigframe(&ksig->ka, regs, sizeof(sigframe32));
327 328
328 if (frame == (void __user *) -1UL) 329 if (frame == (void __user *) -1UL)
329 goto give_sigsegv; 330 return -EFAULT;
330 331
331 if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32)) 332 if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
332 goto give_sigsegv; 333 return -EFAULT;
333 334
334 if (save_sigregs32(regs, &frame->sregs)) 335 if (save_sigregs32(regs, &frame->sregs))
335 goto give_sigsegv; 336 return -EFAULT;
336 if (save_sigregs_gprs_high(regs, frame->gprs_high)) 337 if (save_sigregs_gprs_high(regs, frame->gprs_high))
337 goto give_sigsegv; 338 return -EFAULT;
338 if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs)) 339 if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
339 goto give_sigsegv; 340 return -EFAULT;
340 341
341 /* Set up to return from userspace. If provided, use a stub 342 /* Set up to return from userspace. If provided, use a stub
342 already in userspace. */ 343 already in userspace. */
343 if (ka->sa.sa_flags & SA_RESTORER) { 344 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
344 regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE; 345 regs->gprs[14] = (__u64 __force) ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
345 } else { 346 } else {
346 regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE; 347 regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
347 if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, 348 if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
348 (u16 __force __user *)(frame->retcode))) 349 (u16 __force __user *)(frame->retcode)))
349 goto give_sigsegv; 350 return -EFAULT;
350 } 351 }
351 352
352 /* Set up backchain. */ 353 /* Set up backchain. */
353 if (__put_user(regs->gprs[15], (unsigned int __user *) frame)) 354 if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
354 goto give_sigsegv; 355 return -EFAULT;
355 356
356 /* Set up registers for signal handler */ 357 /* Set up registers for signal handler */
357 regs->gprs[15] = (__force __u64) frame; 358 regs->gprs[15] = (__force __u64) frame;
@@ -359,7 +360,7 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
359 regs->psw.mask = PSW_MASK_BA | 360 regs->psw.mask = PSW_MASK_BA |
360 (PSW_USER_BITS & PSW_MASK_ASC) | 361 (PSW_USER_BITS & PSW_MASK_ASC) |
361 (regs->psw.mask & ~PSW_MASK_ASC); 362 (regs->psw.mask & ~PSW_MASK_ASC);
362 regs->psw.addr = (__force __u64) ka->sa.sa_handler; 363 regs->psw.addr = (__force __u64) ksig->ka.sa.sa_handler;
363 364
364 regs->gprs[2] = map_signal(sig); 365 regs->gprs[2] = map_signal(sig);
365 regs->gprs[3] = (__force __u64) &frame->sc; 366 regs->gprs[3] = (__force __u64) &frame->sc;
@@ -376,25 +377,21 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
376 377
377 /* Place signal number on stack to allow backtrace from handler. */ 378 /* Place signal number on stack to allow backtrace from handler. */
378 if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo)) 379 if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
379 goto give_sigsegv; 380 return -EFAULT;
380 return 0; 381 return 0;
381
382give_sigsegv:
383 force_sigsegv(sig, current);
384 return -EFAULT;
385} 382}
386 383
387static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, 384static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
388 sigset_t *set, struct pt_regs * regs) 385 struct pt_regs *regs)
389{ 386{
390 int err = 0; 387 int err = 0;
391 rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32)); 388 rt_sigframe32 __user *frame = get_sigframe(&ksig->ka, regs, sizeof(rt_sigframe32));
392 389
393 if (frame == (void __user *) -1UL) 390 if (frame == (void __user *) -1UL)
394 goto give_sigsegv; 391 return -EFAULT;
395 392
396 if (copy_siginfo_to_user32(&frame->info, info)) 393 if (copy_siginfo_to_user32(&frame->info, &ksig->info))
397 goto give_sigsegv; 394 return -EFAULT;
398 395
399 /* Create the ucontext. */ 396 /* Create the ucontext. */
400 err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags); 397 err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags);
@@ -404,22 +401,22 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
404 err |= save_sigregs_gprs_high(regs, frame->gprs_high); 401 err |= save_sigregs_gprs_high(regs, frame->gprs_high);
405 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 402 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
406 if (err) 403 if (err)
407 goto give_sigsegv; 404 return -EFAULT;
408 405
409 /* Set up to return from userspace. If provided, use a stub 406 /* Set up to return from userspace. If provided, use a stub
410 already in userspace. */ 407 already in userspace. */
411 if (ka->sa.sa_flags & SA_RESTORER) { 408 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
412 regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE; 409 regs->gprs[14] = (__u64 __force) ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
413 } else { 410 } else {
414 regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE; 411 regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
415 if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, 412 if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
416 (u16 __force __user *)(frame->retcode))) 413 (u16 __force __user *)(frame->retcode)))
417 goto give_sigsegv; 414 return -EFAULT;
418 } 415 }
419 416
420 /* Set up backchain. */ 417 /* Set up backchain. */
421 if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame)) 418 if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame))
422 goto give_sigsegv; 419 return -EFAULT;
423 420
424 /* Set up registers for signal handler */ 421 /* Set up registers for signal handler */
425 regs->gprs[15] = (__force __u64) frame; 422 regs->gprs[15] = (__force __u64) frame;
@@ -427,36 +424,30 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
427 regs->psw.mask = PSW_MASK_BA | 424 regs->psw.mask = PSW_MASK_BA |
428 (PSW_USER_BITS & PSW_MASK_ASC) | 425 (PSW_USER_BITS & PSW_MASK_ASC) |
429 (regs->psw.mask & ~PSW_MASK_ASC); 426 (regs->psw.mask & ~PSW_MASK_ASC);
430 regs->psw.addr = (__u64 __force) ka->sa.sa_handler; 427 regs->psw.addr = (__u64 __force) ksig->ka.sa.sa_handler;
431 428
432 regs->gprs[2] = map_signal(sig); 429 regs->gprs[2] = map_signal(ksig->sig);
433 regs->gprs[3] = (__force __u64) &frame->info; 430 regs->gprs[3] = (__force __u64) &frame->info;
434 regs->gprs[4] = (__force __u64) &frame->uc; 431 regs->gprs[4] = (__force __u64) &frame->uc;
435 regs->gprs[5] = task_thread_info(current)->last_break; 432 regs->gprs[5] = task_thread_info(current)->last_break;
436 return 0; 433 return 0;
437
438give_sigsegv:
439 force_sigsegv(sig, current);
440 return -EFAULT;
441} 434}
442 435
443/* 436/*
444 * OK, we're invoking a handler 437 * OK, we're invoking a handler
445 */ 438 */
446 439
447void handle_signal32(unsigned long sig, struct k_sigaction *ka, 440void handle_signal32(struct ksignal *ksig, sigset_t *oldset,
448 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) 441 struct pt_regs *regs)
449{ 442{
450 int ret; 443 int ret;
451 444
452 /* Set up the stack frame */ 445 /* Set up the stack frame */
453 if (ka->sa.sa_flags & SA_SIGINFO) 446 if (ksig->ka.sa.sa_flags & SA_SIGINFO)
454 ret = setup_rt_frame32(sig, ka, info, oldset, regs); 447 ret = setup_rt_frame32(ksig, oldset, regs);
455 else 448 else
456 ret = setup_frame32(sig, ka, oldset, regs); 449 ret = setup_frame32(ksig, oldset, regs);
457 if (ret) 450
458 return; 451 signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP));
459 signal_delivered(sig, info, ka, regs,
460 test_thread_flag(TIF_SINGLE_STEP));
461} 452}
462 453