Thanks for the report, Ananth. Ah! The i386 will enter do_notify_resume() with interrupts disabled. Other machines don't do this (x86-64 and powerpc64, anyway). It is often harmless, because if TIF_SIGPENDING is set, we'll first enter get_signal_to_deliver() and implicitly reenable interrupts by virtue of spin_lock_irq + spin_unlock_irq. If we don't enter that path, we get straight to utrace_notify_resume() with interrupts still disabled.
I've merged the following fix in. Please verify that it works well for you. Thanks, Roland diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 68376ff..0000000 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -631,7 +631,8 @@ static inline void set_notify_resume(str * asynchronously, this will be called again before we return to * user mode. * - * Called without locks. + * Called without locks. However, on some machines this may be + * called with interrupts disabled. */ static inline void tracehook_notify_resume(struct pt_regs *regs) { diff --git a/kernel/utrace.c b/kernel/utrace.c index 807384d..0000000 100644 --- a/kernel/utrace.c +++ b/kernel/utrace.c @@ -1857,6 +1857,13 @@ void utrace_resume(struct task_struct *t struct utrace_attached_engine *engine, *next; /* + * Some machines get here with interrupts disabled. The same arch + * code path leads to calling into get_signal_to_deliver(), which + * implicitly reenables them by virtue of spin_unlock_irq. + */ + local_irq_enable(); + + /* * If this flag is still set it's because there was a signal * handler setup done but no report_signal following it. Clear * the flag before we get to user so it doesn't confuse us later.