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.

Reply via email to