diff options
Diffstat (limited to 'arch/powerpc/kernel/signal_64.c')
-rw-r--r-- | arch/powerpc/kernel/signal_64.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 1decf2785530..5462bef898f6 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -96,8 +96,10 @@ long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int | |||
96 | while (1) { | 96 | while (1) { |
97 | current->state = TASK_INTERRUPTIBLE; | 97 | current->state = TASK_INTERRUPTIBLE; |
98 | schedule(); | 98 | schedule(); |
99 | if (do_signal(&saveset, regs)) | 99 | if (do_signal(&saveset, regs)) { |
100 | set_thread_flag(TIF_RESTOREALL); | ||
100 | return 0; | 101 | return 0; |
102 | } | ||
101 | } | 103 | } |
102 | } | 104 | } |
103 | 105 | ||
@@ -152,6 +154,14 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
152 | err |= __put_user(0, &sc->v_regs); | 154 | err |= __put_user(0, &sc->v_regs); |
153 | #endif /* CONFIG_ALTIVEC */ | 155 | #endif /* CONFIG_ALTIVEC */ |
154 | err |= __put_user(&sc->gp_regs, &sc->regs); | 156 | err |= __put_user(&sc->gp_regs, &sc->regs); |
157 | if (!FULL_REGS(regs)) { | ||
158 | /* Zero out the unsaved GPRs to avoid information | ||
159 | leak, and set TIF_SAVE_NVGPRS to ensure that the | ||
160 | registers do actually get saved later. */ | ||
161 | memset(®s->gpr[14], 0, 18 * sizeof(unsigned long)); | ||
162 | set_thread_flag(TIF_SAVE_NVGPRS); | ||
163 | current_thread_info()->nvgprs_frame = &sc->gp_regs; | ||
164 | } | ||
155 | err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); | 165 | err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); |
156 | err |= __copy_to_user(&sc->fp_regs, ¤t->thread.fpr, FP_REGS_SIZE); | 166 | err |= __copy_to_user(&sc->fp_regs, ¤t->thread.fpr, FP_REGS_SIZE); |
157 | err |= __put_user(signr, &sc->signal); | 167 | err |= __put_user(signr, &sc->signal); |
@@ -340,6 +350,7 @@ int sys_swapcontext(struct ucontext __user *old_ctx, | |||
340 | do_exit(SIGSEGV); | 350 | do_exit(SIGSEGV); |
341 | 351 | ||
342 | /* This returns like rt_sigreturn */ | 352 | /* This returns like rt_sigreturn */ |
353 | set_thread_flag(TIF_RESTOREALL); | ||
343 | return 0; | 354 | return 0; |
344 | } | 355 | } |
345 | 356 | ||
@@ -372,7 +383,8 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, | |||
372 | */ | 383 | */ |
373 | do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]); | 384 | do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]); |
374 | 385 | ||
375 | return regs->result; | 386 | set_thread_flag(TIF_RESTOREALL); |
387 | return 0; | ||
376 | 388 | ||
377 | badframe: | 389 | badframe: |
378 | #if DEBUG_SIG | 390 | #if DEBUG_SIG |
@@ -454,9 +466,6 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, | |||
454 | if (err) | 466 | if (err) |
455 | goto badframe; | 467 | goto badframe; |
456 | 468 | ||
457 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
458 | ptrace_notify(SIGTRAP); | ||
459 | |||
460 | return 1; | 469 | return 1; |
461 | 470 | ||
462 | badframe: | 471 | badframe: |
@@ -502,6 +511,8 @@ static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) | |||
502 | * we only get here if there is a handler, we dont restart. | 511 | * we only get here if there is a handler, we dont restart. |
503 | */ | 512 | */ |
504 | regs->result = -EINTR; | 513 | regs->result = -EINTR; |
514 | regs->gpr[3] = EINTR; | ||
515 | regs->ccr |= 0x10000000; | ||
505 | break; | 516 | break; |
506 | case -ERESTARTSYS: | 517 | case -ERESTARTSYS: |
507 | /* ERESTARTSYS means to restart the syscall if there is no | 518 | /* ERESTARTSYS means to restart the syscall if there is no |
@@ -509,6 +520,8 @@ static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) | |||
509 | */ | 520 | */ |
510 | if (!(ka->sa.sa_flags & SA_RESTART)) { | 521 | if (!(ka->sa.sa_flags & SA_RESTART)) { |
511 | regs->result = -EINTR; | 522 | regs->result = -EINTR; |
523 | regs->gpr[3] = EINTR; | ||
524 | regs->ccr |= 0x10000000; | ||
512 | break; | 525 | break; |
513 | } | 526 | } |
514 | /* fallthrough */ | 527 | /* fallthrough */ |