Commit e320343c authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] signal-race-fixes: x86-64 support

  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.

From: Mikael Pettersson <mikpe@csd.uu.se>

  The signal-race-fixes patch in 2.6.8-rc2-mm1 appears to have broken
  x86-64's ia32 emulation.

  When forcing a SIGSEGV the old code updated "*ka", where ka was a pointer
  to current's k_sigaction for SIGSEGV.  Now "ka_copy" points to a copy of
  that structure, so assigning "*ka_copy" doesn't do what we want.  Instead do
  the assignment via current->...  just like the normal signal delivery code
  does.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent bebbdf18
......@@ -288,7 +288,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (ka->sa.sa_flags & SA_RESTORER) {
err |= __put_user(ka->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;
}
......@@ -337,11 +337,9 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
*/
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,
sigset_t *oldset, struct pt_regs *regs)
{
struct k_sigaction *ka = &current->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);
......@@ -378,9 +376,6 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
#endif
setup_rt_frame(sig, ka, info, oldset, regs);
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
......@@ -397,6 +392,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
*/
int do_signal(struct pt_regs *regs, sigset_t *oldset)
{
struct k_sigaction ka;
siginfo_t info;
int signr;
......@@ -418,7 +414,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
if (!oldset)
oldset = &current->blocked;
signr = get_signal_to_deliver(&info, regs, NULL);
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
/* Reenable any watchpoints before delivering the
* signal to user space. The processor register will
......@@ -429,7 +425,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
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, oldset, regs);
return 1;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment