err |= restore_i387(buf);
} else {
struct task_struct *me = current;
- if (used_math()) {
+ if (me->used_math) {
clear_fpu(me);
- clear_used_math();
+ me->used_math = 0;
}
}
}
struct pt_regs *regs, unsigned long mask)
{
int tmp, err = 0;
+ unsigned long eflags;
tmp = 0;
__asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
err |= __put_user(current->thread.error_code, &sc->err);
err |= __put_user(regs->eip, &sc->eip);
err |= __put_user(regs->xcs, (unsigned int __user *)&sc->cs);
- err |= __put_user(regs->eflags, &sc->eflags);
+
+ /*
+ * Iff TF was set because the program is being single-stepped by a
+ * debugger, don't save that information on the signal stack.. We
+ * don't want debugging to change state.
+ */
+ eflags = regs->eflags;
+ if (current->ptrace & PT_DTRACE)
+ eflags &= ~TF_MASK;
+ err |= __put_user(eflags, &sc->eflags);
err |= __put_user(regs->esp, &sc->esp_at_signal);
err |= __put_user(regs->xss, (unsigned int __user *)&sc->ss);
? current_thread_info()->exec_domain->signal_invmap[sig]
: sig;
- err = __put_user(usig, &frame->sig);
+ err |= __put_user(usig, &frame->sig);
if (err)
goto give_sigsegv;
- err = setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
+ err |= setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
if (err)
goto give_sigsegv;
if (_NSIG_WORDS > 1) {
- err = __copy_to_user(&frame->extramask, &set->sig[1],
+ err |= __copy_to_user(&frame->extramask, &set->sig[1],
sizeof(frame->extramask));
- if (err)
- goto give_sigsegv;
}
+ if (err)
+ goto give_sigsegv;
- restorer = &__kernel_sigreturn;
+ restorer = current->mm->context.vdso + (long)&__kernel_sigreturn;
if (ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
* The tracer may want to single-step inside the
* handler too.
*/
- regs->eflags &= ~TF_MASK;
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
+ if (regs->eflags & TF_MASK) {
+ regs->eflags &= ~TF_MASK;
+ if (current->ptrace & PT_DTRACE)
+ ptrace_notify(SIGTRAP);
+ }
#if DEBUG_SIG
printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
goto give_sigsegv;
/* Set up to return from userspace. */
- restorer = &__kernel_rt_sigreturn;
+ restorer = current->mm->context.vdso + (long)&__kernel_rt_sigreturn;
if (ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
+
err |= __put_user(restorer, &frame->pretcode);
/*
* The tracer may want to single-step inside the
* handler too.
*/
- regs->eflags &= ~TF_MASK;
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
+ if (regs->eflags & TF_MASK) {
+ regs->eflags &= ~TF_MASK;
+ if (current->ptrace & PT_DTRACE)
+ ptrace_notify(SIGTRAP);
+ }
#if DEBUG_SIG
printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",