diff options
Diffstat (limited to 'arch/ia64/kernel/signal.c')
-rw-r--r-- | arch/ia64/kernel/signal.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 19be1f840..a0cca9da7 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -94,7 +94,7 @@ static long restore_sigcontext (struct sigcontext *sc, struct pt_regs *pt) { struct switch_stack *sw = (struct switch_stack *) pt - 1; - unsigned long ip, flags, nat, um; + unsigned long ip, flags, nat, um, cfm; long err; /* restore scratch that always needs gets updated during signal delivery: */ @@ -102,20 +102,24 @@ restore_sigcontext (struct sigcontext *sc, struct pt_regs *pt) err |= __get_user(nat, &sc->sc_nat); err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */ - err |= __get_user(pt->ar_fpsr, &sc->sc_ar_fpsr); - err |= __get_user(pt->ar_pfs, &sc->sc_ar_pfs); + err |= __get_user(cfm, &sc->sc_cfm); err |= __get_user(um, &sc->sc_um); /* user mask */ err |= __get_user(pt->ar_rsc, &sc->sc_ar_rsc); err |= __get_user(pt->ar_ccv, &sc->sc_ar_ccv); err |= __get_user(pt->ar_unat, &sc->sc_ar_unat); + err |= __get_user(pt->ar_fpsr, &sc->sc_ar_fpsr); + err |= __get_user(pt->ar_pfs, &sc->sc_ar_pfs); err |= __get_user(pt->pr, &sc->sc_pr); /* predicates */ err |= __get_user(pt->b0, &sc->sc_br[0]); /* b0 (rp) */ - err |= __get_user(pt->b6, &sc->sc_br[6]); + err |= __get_user(pt->b6, &sc->sc_br[6]); /* b6 */ + err |= __get_user(pt->b7, &sc->sc_br[7]); /* b7 */ err |= __copy_from_user(&pt->r1, &sc->sc_gr[1], 3*8); /* r1-r3 */ err |= __copy_from_user(&pt->r8, &sc->sc_gr[8], 4*8); /* r8-r11 */ err |= __copy_from_user(&pt->r12, &sc->sc_gr[12], 4*8); /* r12-r15 */ err |= __copy_from_user(&pt->r16, &sc->sc_gr[16], 16*8); /* r16-r31 */ + pt->cr_ifs = cfm | (1UL << 63); + /* establish new instruction pointer: */ pt->cr_iip = ip & ~0x3UL; ia64_psr(pt)->ri = ip & 0x3; @@ -240,6 +244,7 @@ setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct pt_regs *pt) nat = ia64_get_nat_bits(pt, sw); err = __put_user(flags, &sc->sc_flags); + err |= __put_user(nat, &sc->sc_nat); err |= PUT_SIGSET(mask, &sc->sc_mask); err |= __put_user(pt->cr_ipsr & IA64_PSR_UM, &sc->sc_um); @@ -255,8 +260,8 @@ setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct pt_regs *pt) err |= __copy_to_user(&sc->sc_gr[1], &pt->r1, 3*8); /* r1-r3 */ err |= __copy_to_user(&sc->sc_gr[8], &pt->r8, 4*8); /* r8-r11 */ - err |= __copy_to_user(&sc->sc_gr[12], &pt->r12, 4*8); /* r12-r15 */ - err |= __copy_to_user(&sc->sc_gr[16], &pt->r16, 16*8); /* r16-r31 */ + err |= __copy_to_user(&sc->sc_gr[12], &pt->r12, 4*8); /* r12-r15 */ + err |= __copy_to_user(&sc->sc_gr[16], &pt->r16, 16*8); /* r16-r31 */ err |= __put_user(pt->cr_iip + ia64_psr(pt)->ri, &sc->sc_ip); err |= __put_user(pt->r12, &sc->sc_gr[12]); /* r12 */ @@ -415,10 +420,12 @@ ia64_do_signal (sigset_t *oldset, struct pt_regs *pt, long in_syscall) if ((current->flags & PF_PTRACED) && signr != SIGKILL) { /* Let the debugger run. */ current->exit_code = signr; + current->thread.siginfo = &info; set_current_state(TASK_STOPPED); notify_parent(current, SIGCHLD); schedule(); signr = current->exit_code; + current->thread.siginfo = 0; /* We're back. Did the debugger cancel the sig? */ if (!signr) |