diff options
Diffstat (limited to 'arch/ia64/kernel/signal.c')
-rw-r--r-- | arch/ia64/kernel/signal.c | 46 |
1 files changed, 21 insertions, 25 deletions
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 33cab9a8adff..6d92170be457 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -309,12 +309,11 @@ force_sigsegv_info (int sig, void __user *addr) | |||
309 | si.si_uid = from_kuid_munged(current_user_ns(), current_uid()); | 309 | si.si_uid = from_kuid_munged(current_user_ns(), current_uid()); |
310 | si.si_addr = addr; | 310 | si.si_addr = addr; |
311 | force_sig_info(SIGSEGV, &si, current); | 311 | force_sig_info(SIGSEGV, &si, current); |
312 | return 0; | 312 | return 1; |
313 | } | 313 | } |
314 | 314 | ||
315 | static long | 315 | static long |
316 | setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, | 316 | setup_frame(struct ksignal *ksig, sigset_t *set, struct sigscratch *scr) |
317 | struct sigscratch *scr) | ||
318 | { | 317 | { |
319 | extern char __kernel_sigtramp[]; | 318 | extern char __kernel_sigtramp[]; |
320 | unsigned long tramp_addr, new_rbs = 0, new_sp; | 319 | unsigned long tramp_addr, new_rbs = 0, new_sp; |
@@ -323,7 +322,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, | |||
323 | 322 | ||
324 | new_sp = scr->pt.r12; | 323 | new_sp = scr->pt.r12; |
325 | tramp_addr = (unsigned long) __kernel_sigtramp; | 324 | tramp_addr = (unsigned long) __kernel_sigtramp; |
326 | if (ka->sa.sa_flags & SA_ONSTACK) { | 325 | if (ksig->ka.sa.sa_flags & SA_ONSTACK) { |
327 | int onstack = sas_ss_flags(new_sp); | 326 | int onstack = sas_ss_flags(new_sp); |
328 | 327 | ||
329 | if (onstack == 0) { | 328 | if (onstack == 0) { |
@@ -347,29 +346,29 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, | |||
347 | */ | 346 | */ |
348 | check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN; | 347 | check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN; |
349 | if (!likely(on_sig_stack(check_sp))) | 348 | if (!likely(on_sig_stack(check_sp))) |
350 | return force_sigsegv_info(sig, (void __user *) | 349 | return force_sigsegv_info(ksig->sig, (void __user *) |
351 | check_sp); | 350 | check_sp); |
352 | } | 351 | } |
353 | } | 352 | } |
354 | frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN); | 353 | frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN); |
355 | 354 | ||
356 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 355 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
357 | return force_sigsegv_info(sig, frame); | 356 | return force_sigsegv_info(ksig->sig, frame); |
358 | 357 | ||
359 | err = __put_user(sig, &frame->arg0); | 358 | err = __put_user(ksig->sig, &frame->arg0); |
360 | err |= __put_user(&frame->info, &frame->arg1); | 359 | err |= __put_user(&frame->info, &frame->arg1); |
361 | err |= __put_user(&frame->sc, &frame->arg2); | 360 | err |= __put_user(&frame->sc, &frame->arg2); |
362 | err |= __put_user(new_rbs, &frame->sc.sc_rbs_base); | 361 | err |= __put_user(new_rbs, &frame->sc.sc_rbs_base); |
363 | err |= __put_user(0, &frame->sc.sc_loadrs); /* initialize to zero */ | 362 | err |= __put_user(0, &frame->sc.sc_loadrs); /* initialize to zero */ |
364 | err |= __put_user(ka->sa.sa_handler, &frame->handler); | 363 | err |= __put_user(ksig->ka.sa.sa_handler, &frame->handler); |
365 | 364 | ||
366 | err |= copy_siginfo_to_user(&frame->info, info); | 365 | err |= copy_siginfo_to_user(&frame->info, &ksig->info); |
367 | 366 | ||
368 | err |= __save_altstack(&frame->sc.sc_stack, scr->pt.r12); | 367 | err |= __save_altstack(&frame->sc.sc_stack, scr->pt.r12); |
369 | err |= setup_sigcontext(&frame->sc, set, scr); | 368 | err |= setup_sigcontext(&frame->sc, set, scr); |
370 | 369 | ||
371 | if (unlikely(err)) | 370 | if (unlikely(err)) |
372 | return force_sigsegv_info(sig, frame); | 371 | return force_sigsegv_info(ksig->sig, frame); |
373 | 372 | ||
374 | scr->pt.r12 = (unsigned long) frame - 16; /* new stack pointer */ | 373 | scr->pt.r12 = (unsigned long) frame - 16; /* new stack pointer */ |
375 | scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */ | 374 | scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */ |
@@ -394,22 +393,20 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, | |||
394 | 393 | ||
395 | #if DEBUG_SIG | 394 | #if DEBUG_SIG |
396 | printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%p\n", | 395 | printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%p\n", |
397 | current->comm, current->pid, sig, scr->pt.r12, frame->sc.sc_ip, frame->handler); | 396 | current->comm, current->pid, ksig->sig, scr->pt.r12, frame->sc.sc_ip, frame->handler); |
398 | #endif | 397 | #endif |
399 | return 1; | 398 | return 0; |
400 | } | 399 | } |
401 | 400 | ||
402 | static long | 401 | static long |
403 | handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | 402 | handle_signal (struct ksignal *ksig, struct sigscratch *scr) |
404 | struct sigscratch *scr) | ||
405 | { | 403 | { |
406 | if (!setup_frame(sig, ka, info, sigmask_to_save(), scr)) | 404 | int ret = setup_frame(ksig, sigmask_to_save(), scr); |
407 | return 0; | ||
408 | 405 | ||
409 | signal_delivered(sig, info, ka, &scr->pt, | 406 | if (!ret) |
410 | test_thread_flag(TIF_SINGLESTEP)); | 407 | signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); |
411 | 408 | ||
412 | return 1; | 409 | return ret; |
413 | } | 410 | } |
414 | 411 | ||
415 | /* | 412 | /* |
@@ -419,17 +416,16 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
419 | void | 416 | void |
420 | ia64_do_signal (struct sigscratch *scr, long in_syscall) | 417 | ia64_do_signal (struct sigscratch *scr, long in_syscall) |
421 | { | 418 | { |
422 | struct k_sigaction ka; | ||
423 | siginfo_t info; | ||
424 | long restart = in_syscall; | 419 | long restart = in_syscall; |
425 | long errno = scr->pt.r8; | 420 | long errno = scr->pt.r8; |
421 | struct ksignal ksig; | ||
426 | 422 | ||
427 | /* | 423 | /* |
428 | * This only loops in the rare cases of handle_signal() failing, in which case we | 424 | * This only loops in the rare cases of handle_signal() failing, in which case we |
429 | * need to push through a forced SIGSEGV. | 425 | * need to push through a forced SIGSEGV. |
430 | */ | 426 | */ |
431 | while (1) { | 427 | while (1) { |
432 | int signr = get_signal_to_deliver(&info, &ka, &scr->pt, NULL); | 428 | get_signal(&ksig); |
433 | 429 | ||
434 | /* | 430 | /* |
435 | * get_signal_to_deliver() may have run a debugger (via notify_parent()) | 431 | * get_signal_to_deliver() may have run a debugger (via notify_parent()) |
@@ -446,7 +442,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) | |||
446 | */ | 442 | */ |
447 | restart = 0; | 443 | restart = 0; |
448 | 444 | ||
449 | if (signr <= 0) | 445 | if (ksig.sig <= 0) |
450 | break; | 446 | break; |
451 | 447 | ||
452 | if (unlikely(restart)) { | 448 | if (unlikely(restart)) { |
@@ -458,7 +454,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) | |||
458 | break; | 454 | break; |
459 | 455 | ||
460 | case ERESTARTSYS: | 456 | case ERESTARTSYS: |
461 | if ((ka.sa.sa_flags & SA_RESTART) == 0) { | 457 | if ((ksig.ka.sa.sa_flags & SA_RESTART) == 0) { |
462 | scr->pt.r8 = EINTR; | 458 | scr->pt.r8 = EINTR; |
463 | /* note: scr->pt.r10 is already -1 */ | 459 | /* note: scr->pt.r10 is already -1 */ |
464 | break; | 460 | break; |
@@ -473,7 +469,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall) | |||
473 | * Whee! Actually deliver the signal. If the delivery failed, we need to | 469 | * Whee! Actually deliver the signal. If the delivery failed, we need to |
474 | * continue to iterate in this loop so we can deliver the SIGSEGV... | 470 | * continue to iterate in this loop so we can deliver the SIGSEGV... |
475 | */ | 471 | */ |
476 | if (handle_signal(signr, &ka, &info, scr)) | 472 | if (handle_signal(&ksig, scr)) |
477 | return; | 473 | return; |
478 | } | 474 | } |
479 | 475 | ||