From: Andi Kleen Add the signal race changes to x86-64 to make it compile again. Didn't merge the more pointless changes from i386. Also remove the special SA_ONESHOT handling, doesn't seem to be needed anymore. --- 25-akpm/arch/x86_64/ia32/ia32_signal.c | 38 +++++++++++++------------- 25-akpm/arch/x86_64/kernel/signal.c | 48 +++++++++++++++------------------ 2 files changed, 42 insertions(+), 44 deletions(-) diff -puN arch/x86_64/ia32/ia32_signal.c~signal-race-fix-x86_64 arch/x86_64/ia32/ia32_signal.c --- 25/arch/x86_64/ia32/ia32_signal.c~signal-race-fix-x86_64 2004-07-27 02:03:10.276563240 -0700 +++ 25-akpm/arch/x86_64/ia32/ia32_signal.c 2004-07-27 02:03:10.284562024 -0700 @@ -389,7 +389,7 @@ ia32_setup_sigcontext(struct sigcontext_ * Determine which stack to use.. */ static void __user * -get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) +get_sigframe(struct k_sigaction *ka_copy, struct pt_regs *regs, size_t frame_size) { unsigned long rsp; @@ -397,28 +397,28 @@ get_sigframe(struct k_sigaction *ka, str rsp = regs->rsp; /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { + if (ka_copy->sa.sa_flags & SA_ONSTACK) { if (sas_ss_flags(rsp) == 0) rsp = current->sas_ss_sp + current->sas_ss_size; } /* This is the legacy signal stack switching. */ else if ((regs->ss & 0xffff) != __USER_DS && - !(ka->sa.sa_flags & SA_RESTORER) && - ka->sa.sa_restorer) { - rsp = (unsigned long) ka->sa.sa_restorer; + !(ka_copy->sa.sa_flags & SA_RESTORER) && + ka_copy->sa.sa_restorer) { + rsp = (unsigned long)ka_copy->sa.sa_restorer; } return (void __user *)((rsp - frame_size) & -8UL); } -void ia32_setup_frame(int sig, struct k_sigaction *ka, - compat_sigset_t *set, struct pt_regs * regs) +void ia32_setup_frame(int sig, struct k_sigaction *ka_copy, + compat_sigset_t *set, struct pt_regs *regs) { struct sigframe __user *frame; int err = 0; - frame = get_sigframe(ka, regs, sizeof(*frame)); + frame = get_sigframe(ka_copy, regs, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; @@ -449,8 +449,8 @@ void ia32_setup_frame(int sig, struct k_ /* Return stub is in 32bit vsyscall page */ { void __user *restorer = VSYSCALL32_SIGRETURN; - if (ka->sa.sa_flags & SA_RESTORER) - restorer = ka->sa.sa_restorer; + if (ka_copy->sa.sa_flags & SA_RESTORER) + restorer = ka_copy->sa.sa_restorer; err |= __put_user(ptr_to_u32(restorer), &frame->pretcode); } /* These are actually not used anymore, but left because some @@ -475,7 +475,7 @@ void ia32_setup_frame(int sig, struct k_ /* Set up registers for signal handler */ regs->rsp = (unsigned long) frame; - regs->rip = (unsigned long) ka->sa.sa_handler; + regs->rip = (unsigned long) ka_copy->sa.sa_handler; asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); @@ -495,17 +495,17 @@ void ia32_setup_frame(int sig, struct k_ give_sigsegv: if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; + ka_copy->sa.sa_handler = SIG_DFL; signal_fault(regs,frame,"32bit signal deliver"); } -void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, - compat_sigset_t *set, struct pt_regs * regs) +void ia32_setup_rt_frame(int sig, struct k_sigaction *ka_copy, + siginfo_t *info, compat_sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; int err = 0; - frame = get_sigframe(ka, regs, sizeof(*frame)); + frame = get_sigframe(ka_copy, regs, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; @@ -542,8 +542,8 @@ void ia32_setup_rt_frame(int sig, struct { void __user *restorer = VSYSCALL32_RTSIGRETURN; - if (ka->sa.sa_flags & SA_RESTORER) - restorer = ka->sa.sa_restorer; + if (ka_copy->sa.sa_flags & SA_RESTORER) + restorer = ka_copy->sa.sa_restorer; err |= __put_user(ptr_to_u32(restorer), &frame->pretcode); } @@ -571,7 +571,7 @@ void ia32_setup_rt_frame(int sig, struct /* Set up registers for signal handler */ regs->rsp = (unsigned long) frame; - regs->rip = (unsigned long) ka->sa.sa_handler; + regs->rip = (unsigned long) ka_copy->sa.sa_handler; asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); @@ -591,7 +591,7 @@ void ia32_setup_rt_frame(int sig, struct give_sigsegv: if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; + current->sighand->action[SIGSEGV-1].sa.sa_handler = SIG_DFL; signal_fault(regs, frame, "32bit rt signal setup"); } diff -puN arch/x86_64/kernel/signal.c~signal-race-fix-x86_64 arch/x86_64/kernel/signal.c --- 25/arch/x86_64/kernel/signal.c~signal-race-fix-x86_64 2004-07-27 02:03:10.279562784 -0700 +++ 25-akpm/arch/x86_64/kernel/signal.c 2004-07-27 02:03:10.285561872 -0700 @@ -232,7 +232,8 @@ get_stack(struct k_sigaction *ka, struct return (void __user *)round_down(rsp - size, 16); } -static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, +static void setup_rt_frame(int sig, struct k_sigaction *ka_copy, + siginfo_t *info, sigset_t *set, struct pt_regs * regs) { struct rt_sigframe __user *frame; @@ -241,7 +242,7 @@ static void setup_rt_frame(int sig, stru struct task_struct *me = current; if (me->used_math) { - fp = get_stack(ka, regs, sizeof(struct _fpstate)); + fp = get_stack(ka_copy, regs, sizeof(struct _fpstate)); frame = (void __user *)round_down((unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8; if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) { @@ -251,14 +252,14 @@ static void setup_rt_frame(int sig, stru if (save_i387(fp) < 0) err |= -1; } else { - frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8; + frame = get_stack(ka_copy, regs, sizeof(struct rt_sigframe)) - 8; } if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) { goto give_sigsegv; } - if (ka->sa.sa_flags & SA_SIGINFO) { + if (ka_copy->sa.sa_flags & SA_SIGINFO) { err |= copy_siginfo_to_user(&frame->info, info); if (err) { goto give_sigsegv; @@ -284,10 +285,10 @@ static void setup_rt_frame(int sig, stru /* Set up to return from userspace. If provided, use a stub already in userspace. */ /* x86-64 should always use SA_RESTORER. */ - if (ka->sa.sa_flags & SA_RESTORER) { - err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); + if (ka_copy->sa.sa_flags & SA_RESTORER) { + err |= __put_user(ka_copy->sa.sa_restorer, &frame->pretcode); } else { - printk("%s forgot to set SA_RESTORER for signal %d.\n", me->comm, sig); + /* could use a vstub here */ goto give_sigsegv; } @@ -313,7 +314,7 @@ static void setup_rt_frame(int sig, stru next argument after the signal number on the stack. */ regs->rsi = (unsigned long)&frame->info; regs->rdx = (unsigned long)&frame->uc; - regs->rip = (unsigned long) ka->sa.sa_handler; + regs->rip = (unsigned long) ka_copy->sa.sa_handler; regs->rsp = (unsigned long)frame; @@ -329,7 +330,7 @@ static void setup_rt_frame(int sig, stru give_sigsegv: if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; + current->sighand->action[SIGSEGV-1].sa.sa_handler = SIG_DFL; signal_fault(regs,frame,"signal deliver"); } @@ -338,11 +339,9 @@ give_sigsegv: */ static void -handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, - struct pt_regs * regs) +handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka_copy, + sigset_t *oldset, struct pt_regs *regs) { - struct k_sigaction *ka = ¤t->sighand->action[sig-1]; - #ifdef DEBUG_SIG printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", current->pid, sig, regs->rip, regs->rsp, regs); @@ -358,7 +357,7 @@ handle_signal(unsigned long sig, siginfo break; case -ERESTARTSYS: - if (!(ka->sa.sa_flags & SA_RESTART)) { + if (!(ka_copy->sa.sa_flags & SA_RESTART)) { regs->rax = -EINTR; break; } @@ -371,20 +370,18 @@ handle_signal(unsigned long sig, siginfo #ifdef CONFIG_IA32_EMULATION if (test_thread_flag(TIF_IA32)) { - if (ka->sa.sa_flags & SA_SIGINFO) - ia32_setup_rt_frame(sig, ka, info, oldset, regs); + if (ka_copy->sa.sa_flags & SA_SIGINFO) + ia32_setup_rt_frame(sig, ka_copy, info, oldset, regs); else - ia32_setup_frame(sig, ka, oldset, regs); + ia32_setup_frame(sig, ka_copy, oldset, regs); } else #endif - setup_rt_frame(sig, ka, info, oldset, regs); - - if (ka->sa.sa_flags & SA_ONESHOT) - ka->sa.sa_handler = SIG_DFL; + setup_rt_frame(sig, ka_copy, info, oldset, regs); - if (!(ka->sa.sa_flags & SA_NODEFER)) { + if (!(ka_copy->sa.sa_flags & SA_NODEFER)) { spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigorsets(¤t->blocked,¤t->blocked, + &ka_copy->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); @@ -398,6 +395,7 @@ handle_signal(unsigned long sig, siginfo */ int do_signal(struct pt_regs *regs, sigset_t *oldset) { + struct k_sigaction ka_copy; siginfo_t info; int signr; @@ -419,7 +417,7 @@ int do_signal(struct pt_regs *regs, sigs if (!oldset) oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, regs, NULL); + signr = get_signal_to_deliver(&info, &ka_copy, regs, NULL); if (signr > 0) { /* Reenable any watchpoints before delivering the * signal to user space. The processor register will @@ -430,7 +428,7 @@ int do_signal(struct pt_regs *regs, sigs asm volatile("movq %0,%%db7" : : "r" (current->thread.debugreg7)); /* Whee! Actually deliver the signal. */ - handle_signal(signr, &info, oldset, regs); + handle_signal(signr, &info, &ka_copy, oldset, regs); return 1; } _