On Wed, Dec 05, 2012 at 04:08:41PM +0000, James Hogan wrote: > +TBIRES tail_end(TBIRES State, unsigned long orig_syscall) > +{ > + struct pt_regs *regs = (struct pt_regs *)State.Sig.pCtx; > + unsigned long flags; > + > + if (user_mode(regs)) { > + local_irq_enable(); > + /* This is actually a crucial little line - if the process > + * needs swapping out, then this is where it happens! > + */ > + if (need_resched()) > + schedule(); > + > + flags = current_thread_info()->flags; > + if (flags & (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME)) { > + /* Note the passing in of the original syscall number. > + * This is used for implementing signal restart. > + */ > + do_notify_resume(regs, orig_syscall != 0, > + orig_syscall, flags); Owww.... So a) you can't get there with !user_mode(regs) b) you handle only one signal (what happens if you fail sigframe allocation, BTW? Sure, you get SIGSEGV delivered. And don't handle it.) c) you read ->flags with no protection whatsoever. It should be done *before* you enable interrupts, and rechecked after you've done do_notify_resume() and redisabled them. The same for schedule(). It really should be a loop; take a look at how it's done on arm and alpha - there that loop is in C, not in asm glue. d) looks like your sigreturn is, indeed, broken. It should *not* have syscall restart logics triggered at all. -- To unsubscribe from this list: send the line "unsubscribe linux-arch" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html