net: Guaranetee the proper ordering of the loopback device.
[safe/jmp/linux-2.6] / include / linux / tracehook.h
index 43bc51b..6186a78 100644 (file)
@@ -103,7 +103,8 @@ static inline void ptrace_report_syscall(struct pt_regs *regs)
  * the system call.  That must prevent normal entry so no system call is
  * made.  If @task ever returns to user mode after this, its register state
  * is unspecified, but should be something harmless like an %ENOSYS error
- * return.
+ * return.  It should preserve enough information so that syscall_rollback()
+ * can work (see asm-generic/syscall.h).
  *
  * Called without locks, just after entering kernel mode.
  */
@@ -243,7 +244,7 @@ static inline int tracehook_prepare_clone(unsigned clone_flags)
  * tracehook_finish_clone - new child created and being attached
  * @child:             new child task
  * @clone_flags:       %CLONE_* flags from clone/fork/vfork system call
- * @trace:             return value from tracehook_clone_prepare()
+ * @trace:             return value from tracehook_prepare_clone()
  *
  * This is called immediately after adding @child to its parent's children list.
  * The @trace value is that returned by tracehook_prepare_clone().
@@ -258,19 +259,20 @@ static inline void tracehook_finish_clone(struct task_struct *child,
 
 /**
  * tracehook_report_clone - in parent, new child is about to start running
- * @trace:             return value from tracehook_clone_prepare()
+ * @trace:             return value from tracehook_prepare_clone()
  * @regs:              parent's user register state
  * @clone_flags:       flags from parent's system call
  * @pid:               new child's PID in the parent's namespace
  * @child:             new child task
  *
- * Called after a child is set up, but before it has been started running.
- * The @trace value is that returned by tracehook_clone_prepare().
- * This is not a good place to block, because the child has not started yet.
- * Suspend the child here if desired, and block in tracehook_clone_complete().
- * This must prevent the child from self-reaping if tracehook_clone_complete()
- * uses the @child pointer; otherwise it might have died and been released by
- * the time tracehook_report_clone_complete() is called.
+ * Called after a child is set up, but before it has been started
+ * running.  @trace is the value returned by tracehook_prepare_clone().
+ * This is not a good place to block, because the child has not started
+ * yet.  Suspend the child here if desired, and then block in
+ * tracehook_report_clone_complete().  This must prevent the child from
+ * self-reaping if tracehook_report_clone_complete() uses the @child
+ * pointer; otherwise it might have died and been released by the time
+ * tracehook_report_clone_complete() is called.
  *
  * Called with no locks held, but the child cannot run until this returns.
  */
@@ -278,7 +280,7 @@ static inline void tracehook_report_clone(int trace, struct pt_regs *regs,
                                          unsigned long clone_flags,
                                          pid_t pid, struct task_struct *child)
 {
-       if (unlikely(trace)) {
+       if (unlikely(trace) || unlikely(clone_flags & CLONE_PTRACE)) {
                /*
                 * The child starts up with an immediate SIGSTOP.
                 */
@@ -289,7 +291,7 @@ static inline void tracehook_report_clone(int trace, struct pt_regs *regs,
 
 /**
  * tracehook_report_clone_complete - new child is running
- * @trace:             return value from tracehook_clone_prepare()
+ * @trace:             return value from tracehook_prepare_clone()
  * @regs:              parent's user register state
  * @clone_flags:       flags from parent's system call
  * @pid:               new child's PID in the parent's namespace
@@ -346,7 +348,7 @@ static inline void tracehook_prepare_release_task(struct task_struct *task)
 }
 
 /**
- * tracehook_finish_release_task - task is being reaped, clean up tracing
+ * tracehook_finish_release_task - final tracing clean-up
  * @task:              task in %EXIT_DEAD state
  *
  * This is called in release_task() when @task is being in the middle of
@@ -485,14 +487,20 @@ static inline int tracehook_notify_jctl(int notify, int why)
        return notify || (current->ptrace & PT_PTRACED);
 }
 
+#define DEATH_REAP                     -1
+#define DEATH_DELAYED_GROUP_LEADER     -2
+
 /**
  * tracehook_notify_death - task is dead, ready to notify parent
  * @task:              @current task now exiting
  * @death_cookie:      value to pass to tracehook_report_death()
  * @group_dead:                nonzero if this was the last thread in the group to die
  *
- * Return the signal number to send our parent with do_notify_parent(), or
- * zero to send no signal and leave a zombie, or -1 to self-reap right now.
+ * A return value >= 0 means call do_notify_parent() with that signal
+ * number.  Negative return value can be %DEATH_REAP to self-reap right
+ * now, or %DEATH_DELAYED_GROUP_LEADER to a zombie without notifying our
+ * parent.  Note that a return value of 0 means a do_notify_parent() call
+ * that sends no signal, but still wakes up a parent blocked in wait*().
  *
  * Called with write_lock_irq(&tasklist_lock) held.
  */
@@ -500,7 +508,7 @@ static inline int tracehook_notify_death(struct task_struct *task,
                                         void **death_cookie, int group_dead)
 {
        if (task->exit_signal == -1)
-               return task->ptrace ? SIGCHLD : -1;
+               return task->ptrace ? SIGCHLD : DEATH_REAP;
 
        /*
         * If something other than our normal parent is ptracing us, then
@@ -510,21 +518,21 @@ static inline int tracehook_notify_death(struct task_struct *task,
        if (thread_group_empty(task) && !ptrace_reparented(task))
                return task->exit_signal;
 
-       return task->ptrace ? SIGCHLD : 0;
+       return task->ptrace ? SIGCHLD : DEATH_DELAYED_GROUP_LEADER;
 }
 
 /**
  * tracehook_report_death - task is dead and ready to be reaped
  * @task:              @current task now exiting
- * @signal:            signal number sent to parent, or 0 or -1
+ * @signal:            return value from tracheook_notify_death()
  * @death_cookie:      value passed back from tracehook_notify_death()
  * @group_dead:                nonzero if this was the last thread in the group to die
  *
  * Thread has just become a zombie or is about to self-reap.  If positive,
  * @signal is the signal number just sent to the parent (usually %SIGCHLD).
- * If @signal is -1, this thread will self-reap.  If @signal is 0, this is
- * a delayed_group_leader() zombie.  The @death_cookie was passed back by
- * tracehook_notify_death().
+ * If @signal is %DEATH_REAP, this thread will self-reap.  If @signal is
+ * %DEATH_DELAYED_GROUP_LEADER, this is a delayed_group_leader() zombie.
+ * The @death_cookie was passed back by tracehook_notify_death().
  *
  * If normal reaping is not inhibited, @task->exit_state might be changing
  * in parallel.
@@ -537,4 +545,38 @@ static inline void tracehook_report_death(struct task_struct *task,
 {
 }
 
+#ifdef TIF_NOTIFY_RESUME
+/**
+ * set_notify_resume - cause tracehook_notify_resume() to be called
+ * @task:              task that will call tracehook_notify_resume()
+ *
+ * Calling this arranges that @task will call tracehook_notify_resume()
+ * before returning to user mode.  If it's already running in user mode,
+ * it will enter the kernel and call tracehook_notify_resume() soon.
+ * If it's blocked, it will not be woken.
+ */
+static inline void set_notify_resume(struct task_struct *task)
+{
+       if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME))
+               kick_process(task);
+}
+
+/**
+ * tracehook_notify_resume - report when about to return to user mode
+ * @regs:              user-mode registers of @current task
+ *
+ * This is called when %TIF_NOTIFY_RESUME has been set.  Now we are
+ * about to return to user mode, and the user state in @regs can be
+ * inspected or adjusted.  The caller in arch code has cleared
+ * %TIF_NOTIFY_RESUME before the call.  If the flag gets set again
+ * asynchronously, this will be called again before we return to
+ * user mode.
+ *
+ * Called without locks.
+ */
+static inline void tracehook_notify_resume(struct pt_regs *regs)
+{
+}
+#endif /* TIF_NOTIFY_RESUME */
+
 #endif /* <linux/tracehook.h> */