rpms/kernel/devel kernel-2.6.spec, 1.2979, 1.2980 linux-2.6-utrace.patch, 1.52, 1.53

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Thu Mar 8 23:45:40 UTC 2007


Author: davej

Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv16033

Modified Files:
	kernel-2.6.spec linux-2.6-utrace.patch 
Log Message:
* Thu Mar 08 2007 Dave Jones <davej at redhat.com>
- update to latest utrace.



Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.2979
retrieving revision 1.2980
diff -u -r1.2979 -r1.2980
--- kernel-2.6.spec	8 Mar 2007 23:01:15 -0000	1.2979
+++ kernel-2.6.spec	8 Mar 2007 23:45:38 -0000	1.2980
@@ -2071,6 +2071,9 @@
 #  - tux.
 
 %changelog
+* Thu Mar 08 2007 Dave Jones <davej at redhat.com>
+- update to latest utrace.
+
 * Thu Mar 08 2007 John W. Linville <linville at redhat.com>
 - update git-wireless-dev.patch (current as of 2007-03-06)
 

linux-2.6-utrace.patch:
 Documentation/utrace.txt            |  579 +++++++++++
 arch/alpha/kernel/asm-offsets.c     |    2 
 arch/alpha/kernel/entry.S           |    4 
 arch/arm/kernel/ptrace.c            |   36 
 arch/arm26/kernel/ptrace.c          |   32 
 arch/frv/kernel/ptrace.c            |   15 
 arch/i386/kernel/entry.S            |    7 
 arch/i386/kernel/i387.c             |  143 +-
 arch/i386/kernel/process.c          |    3 
 arch/i386/kernel/ptrace.c           |  863 ++++++++--------
 arch/i386/kernel/signal.c           |   37 
 arch/i386/kernel/vm86.c             |    7 
 arch/i386/math-emu/fpu_entry.c      |    6 
 arch/ia64/ia32/ia32_entry.S         |    2 
 arch/ia64/ia32/sys_ia32.c           |  536 +++++++++-
 arch/ia64/kernel/asm-offsets.c      |    2 
 arch/ia64/kernel/fsys.S             |   16 
 arch/ia64/kernel/mca.c              |    2 
 arch/ia64/kernel/ptrace.c           | 1700 ++++++++++++++++----------------
 arch/ia64/kernel/signal.c           |    4 
 arch/mips/kernel/ptrace.c           |   21 
 arch/mips/kernel/sysirix.c          |    2 
 arch/powerpc/kernel/Makefile        |    4 
 arch/powerpc/kernel/asm-offsets.c   |    2 
 arch/powerpc/kernel/process.c       |    5 
 arch/powerpc/kernel/ptrace-common.h |  161 ---
 arch/powerpc/kernel/ptrace.c        |  957 ++++++++++--------
 arch/powerpc/kernel/ptrace32.c      |  436 --------
 arch/powerpc/kernel/signal_32.c     |   55 +
 arch/powerpc/kernel/signal_64.c     |    3 
 arch/powerpc/kernel/sys_ppc32.c     |    5 
 arch/powerpc/lib/sstep.c            |    3 
 arch/ppc/kernel/asm-offsets.c       |    2 
 arch/s390/kernel/Makefile           |    2 
 arch/s390/kernel/compat_linux.c     |    3 
 arch/s390/kernel/compat_signal.c    |    5 
 arch/s390/kernel/compat_wrapper.S   |    2 
 arch/s390/kernel/process.c          |    3 
 arch/s390/kernel/ptrace.c           | 1118 ++++++++++-----------
 arch/s390/kernel/signal.c           |    3 
 arch/s390/kernel/traps.c            |    6 
 arch/sparc64/kernel/Makefile        |    2 
 arch/sparc64/kernel/binfmt_aout32.c |    2 
 arch/sparc64/kernel/entry.S         |    6 
 arch/sparc64/kernel/process.c       |    3 
 arch/sparc64/kernel/ptrace.c        | 1222 ++++++++++++-----------
 arch/sparc64/kernel/signal.c        |    2 
 arch/sparc64/kernel/signal32.c      |    2 
 arch/sparc64/kernel/sys_sparc32.c   |    3 
 arch/sparc64/kernel/systbls.S       |    4 
 arch/x86_64/ia32/fpu32.c            |   92 +
 arch/x86_64/ia32/ia32_aout.c        |    6 
 arch/x86_64/ia32/ia32_signal.c      |    7 
 arch/x86_64/ia32/ia32entry.S        |    2 
 arch/x86_64/ia32/ptrace32.c         |  724 +++++++++----
 arch/x86_64/ia32/sys_ia32.c         |    5 
 arch/x86_64/kernel/process.c        |    5 
 arch/x86_64/kernel/ptrace.c         |  662 +++++++-----
 arch/x86_64/kernel/signal.c         |   28 
 arch/x86_64/kernel/traps.c          |    8 
 arch/x86_64/mm/fault.c              |    4 
 drivers/connector/cn_proc.c         |    4 
 fs/binfmt_aout.c                    |    6 
 fs/binfmt_elf.c                     |    6 
 fs/binfmt_elf_fdpic.c               |    7 
 fs/binfmt_flat.c                    |    3 
 fs/binfmt_som.c                     |    2 
 fs/exec.c                           |   11 
 fs/proc/array.c                     |   12 
 fs/proc/base.c                      |   57 -
 include/asm-i386/i387.h             |   13 
 include/asm-i386/signal.h           |    4 
 include/asm-i386/thread_info.h      |    7 
 include/asm-i386/tracehook.h        |   57 +
 include/asm-ia64/elf.h              |   24 
 include/asm-ia64/tracehook.h        |   89 +
 include/asm-powerpc/tracehook.h     |   88 +
 include/asm-s390/tracehook.h        |   61 +
 include/asm-sparc64/tracehook.h     |   52 
 include/asm-x86_64/fpu32.h          |    3 
 include/asm-x86_64/thread_info.h    |    3 
 include/asm-x86_64/tracehook.h      |   61 +
 include/linux/init_task.h           |    3 
 include/linux/ptrace.h              |  236 +++-
 include/linux/sched.h               |   25 
 include/linux/tracehook.h           |  715 +++++++++++++
 include/linux/utrace.h              |  510 +++++++++
 init/Kconfig                        |   29 
 kernel/Makefile                     |    4 
 kernel/exit.c                       |  238 +---
 kernel/fork.c                       |   61 -
 kernel/ptrace.c                     | 1773 +++++++++++++++++++++++++++------
 kernel/signal.c                     |  211 ----
 kernel/sys.c                        |    2 
 kernel/sys_ni.c                     |    4 
 kernel/timer.c                      |    6 
 kernel/tsacct.c                     |    2 
 kernel/utrace.c                     | 1892 ++++++++++++++++++++++++++++++++++++
 security/selinux/hooks.c            |   54 -
 security/selinux/include/objsec.h   |    1 
 100 files changed, 10830 insertions(+), 5089 deletions(-)

Index: linux-2.6-utrace.patch
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/linux-2.6-utrace.patch,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- linux-2.6-utrace.patch	18 Feb 2007 02:52:58 -0000	1.52
+++ linux-2.6-utrace.patch	8 Mar 2007 23:45:38 -0000	1.53
@@ -565,7 +565,7 @@
 +#endif
 --- linux-2.6/include/linux/sched.h
 +++ linux-2.6/include/linux/sched.h
-@@ -803,7 +803,6 @@ struct task_struct {
+@@ -802,7 +802,6 @@ struct task_struct {
  	struct thread_info *thread_info;
  	atomic_t usage;
  	unsigned long flags;	/* per process flags, defined below */
@@ -573,7 +573,7 @@
  
  	int lock_depth;		/* BKL lock depth */
  
-@@ -835,12 +834,6 @@ struct task_struct {
+@@ -834,12 +833,6 @@ struct task_struct {
  #endif
  
  	struct list_head tasks;
@@ -586,7 +586,7 @@
  
  	struct mm_struct *mm, *active_mm;
  
-@@ -860,15 +853,13 @@ struct task_struct {
+@@ -859,15 +852,13 @@ struct task_struct {
  	unsigned long stack_canary;
  #endif
  	/* 
@@ -604,7 +604,7 @@
  	 */
  	struct list_head children;	/* list of my children */
  	struct list_head sibling;	/* linkage in my parent's children list */
-@@ -951,6 +942,11 @@ struct task_struct {
+@@ -950,6 +941,11 @@ struct task_struct {
  	struct audit_context *audit_context;
  	seccomp_t seccomp;
  
@@ -616,7 +616,7 @@
  /* Thread group tracking */
     	u32 parent_exec_id;
     	u32 self_exec_id;
-@@ -1004,8 +1000,6 @@ struct task_struct {
+@@ -1003,8 +999,6 @@ struct task_struct {
  
  	struct io_context *io_context;
  
@@ -625,7 +625,7 @@
  /*
   * current io wait handle: wait queue entry to use for io waits
   * If this thread is processing aio, this points at the waitqueue
-@@ -1043,6 +1037,10 @@ struct task_struct {
+@@ -1042,6 +1036,10 @@ struct task_struct {
  	atomic_t fs_excl;	/* holding fs exclusive resources */
  	struct rcu_head rcu;
  
@@ -636,9 +636,9 @@
  	/*
  	 * cache last used pipe for splice
  	 */
-@@ -1330,6 +1328,7 @@ extern int kill_pid_info_as_uid(int, str
- extern int kill_pgrp(struct pid *pid, int sig, int priv);
+@@ -1330,6 +1328,7 @@ extern int kill_pgrp(struct pid *pid, in
  extern int kill_pid(struct pid *pid, int sig, int priv);
+ extern int kill_proc_info(int, struct siginfo *, pid_t);
  extern void do_notify_parent(struct task_struct *, int);
 +extern void do_notify_parent_cldstop(struct task_struct *, int);
  extern void force_sig(int, struct task_struct *);
@@ -1159,12 +1159,13 @@
 +#endif	/* linux/utrace.h */
 --- linux-2.6/include/linux/ptrace.h
 +++ linux-2.6/include/linux/ptrace.h
-@@ -49,66 +49,195 @@
+@@ -49,66 +49,196 @@
  #include <asm/ptrace.h>
  
  #ifdef __KERNEL__
 +#include <linux/compiler.h>
 +#include <linux/types.h>
++#include <linux/errno.h>
 +struct task_struct;
 +struct siginfo;
 +struct rusage;
@@ -3068,7 +3069,7 @@
  		/*
  		 * This signal will be fatal to the whole group.
  		 */
-@@ -1484,8 +1481,7 @@ void do_notify_parent(struct task_struct
+@@ -1485,8 +1482,7 @@ void do_notify_parent(struct task_struct
   	/* do_notify_parent_cldstop should have been called instead.  */
   	BUG_ON(tsk->state & (TASK_STOPPED|TASK_TRACED));
  
@@ -3078,7 +3079,7 @@
  
  	info.si_signo = sig;
  	info.si_errno = 0;
-@@ -1510,7 +1506,7 @@ void do_notify_parent(struct task_struct
+@@ -1511,7 +1507,7 @@ void do_notify_parent(struct task_struct
  
  	psig = tsk->parent->sighand;
  	spin_lock_irqsave(&psig->siglock, flags);
@@ -3087,7 +3088,7 @@
  	    (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN ||
  	     (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) {
  		/*
-@@ -1538,20 +1534,13 @@ void do_notify_parent(struct task_struct
+@@ -1539,20 +1535,13 @@ void do_notify_parent(struct task_struct
  	spin_unlock_irqrestore(&psig->siglock, flags);
  }
  
@@ -3109,7 +3110,7 @@
  	info.si_signo = SIGCHLD;
  	info.si_errno = 0;
  	info.si_pid = tsk->pid;
-@@ -1576,6 +1565,15 @@ static void do_notify_parent_cldstop(str
+@@ -1577,6 +1566,15 @@ static void do_notify_parent_cldstop(str
   		BUG();
   	}
  
@@ -3125,7 +3126,7 @@
  	sighand = parent->sighand;
  	spin_lock_irqsave(&sighand->siglock, flags);
  	if (sighand->action[SIGCHLD-1].sa.sa_handler != SIG_IGN &&
-@@ -1588,110 +1586,6 @@ static void do_notify_parent_cldstop(str
+@@ -1589,110 +1587,6 @@ static void do_notify_parent_cldstop(str
  	spin_unlock_irqrestore(&sighand->siglock, flags);
  }
  
@@ -3236,7 +3237,7 @@
  static void
  finish_stop(int stop_count)
  {
-@@ -1700,7 +1594,7 @@ finish_stop(int stop_count)
+@@ -1701,7 +1595,7 @@ finish_stop(int stop_count)
  	 * a group stop in progress and we are the last to stop,
  	 * report to the parent.  When ptraced, every thread reports itself.
  	 */
@@ -3245,7 +3246,7 @@
  		read_lock(&tasklist_lock);
  		do_notify_parent_cldstop(current, CLD_STOPPED);
  		read_unlock(&tasklist_lock);
-@@ -1827,44 +1721,24 @@ relock:
+@@ -1828,44 +1722,24 @@ relock:
  		    handle_group_stop())
  			goto relock;
  
@@ -3306,7 +3307,7 @@
  		if (ka->sa.sa_handler == SIG_IGN) /* Do nothing.  */
  			continue;
  		if (ka->sa.sa_handler != SIG_DFL) {
-@@ -1913,7 +1787,7 @@ relock:
+@@ -1914,7 +1788,7 @@ relock:
  				spin_lock_irq(&current->sighand->siglock);
  			}
  
@@ -3315,7 +3316,7 @@
  				/* It released the siglock.  */
  				goto relock;
  			}
-@@ -1940,13 +1814,13 @@ relock:
+@@ -1941,13 +1815,13 @@ relock:
  			 * first and our do_group_exit call below will use
  			 * that value and ignore the one we pass it.
  			 */
@@ -3331,7 +3332,7 @@
  		/* NOTREACHED */
  	}
  	spin_unlock_irq(&current->sighand->siglock);
-@@ -1958,7 +1832,6 @@ EXPORT_SYMBOL_GPL(dequeue_signal);
+@@ -1959,7 +1833,6 @@ EXPORT_SYMBOL_GPL(dequeue_signal);
  EXPORT_SYMBOL(flush_signals);
  EXPORT_SYMBOL(force_sig);
  EXPORT_SYMBOL(kill_proc);
@@ -3365,7 +3366,7 @@
  cond_syscall(sys_pciconfig_write);
 --- linux-2.6/kernel/utrace.c
 +++ linux-2.6/kernel/utrace.c
-@@ -0,0 +1,1871 @@
+@@ -0,0 +1,1892 @@
 +/*
 + * utrace infrastructure interface for debugging user processes
 + *
@@ -3570,17 +3571,23 @@
 +	 */
 +	if (((tsk->utrace_flags &~ flags) & UTRACE_ACTION_NOREAP)
 +	    && tsk->exit_state) {
-+		BUG_ON(tsk->exit_state != EXIT_ZOMBIE);
 +		/*
 +		 * While holding the utrace lock, mark that it's been done.
 +		 * For self-reaping, we need to change tsk->exit_state
 +		 * before clearing tsk->utrace_flags, so that the real
-+		 * parent can't see it in EXIT_ZOMBIE momentarily and reap it.
++		 * parent can't see it in EXIT_ZOMBIE momentarily and reap
++		 * it.  If tsk was the group_leader, an exec by another
++		 * thread can release_task it despite our NOREAP.  Holding
++		 * tasklist_lock for reading excludes de_thread until we
++		 * decide what to do.
 +		 */
-+		if (tsk->exit_signal == -1) {
++		read_lock(&tasklist_lock);
++		if (tsk->exit_signal == -1) { /* Self-reaping thread.  */
 +			exit_state = xchg(&tsk->exit_state, EXIT_DEAD);
++			read_unlock(&tasklist_lock);
++
 +			BUG_ON(exit_state != EXIT_ZOMBIE);
-+			exit_state = EXIT_DEAD;
++			exit_state = EXIT_DEAD;	/* Reap it below.  */
 +
 +			/*
 +			 * Now that we've changed its state to DEAD,
@@ -3588,7 +3595,7 @@
 +			 * value without the UTRACE_ACTION_NOREAP bit set.
 +			 */
 +		}
-+		else if (thread_group_empty(tsk)) {
++		else if (thread_group_empty(tsk)) /* Normal solo zombie.  */
 +			/*
 +			 * We need to prevent the real parent from reaping
 +			 * until after we've called do_notify_parent, below.
@@ -3601,32 +3608,47 @@
 +			 * everything we need to do.
 +			 */
 +			exit_state = EXIT_ZOMBIE;
-+			read_lock(&tasklist_lock);
-+		}
++		else
++			/*
++			 * Delayed group leader, nothing to do yet.
++			 * This is also the situation with the old
++			 * group leader in an exec by another thread,
++			 * which will call release_task itself.
++			 */
++			read_unlock(&tasklist_lock);
++
 +	}
 +
 +	tsk->utrace_flags = flags;
 +	if (flags)
 +		spin_unlock(&utrace->lock);
-+	else {
++	else
 +		rcu_utrace_free(utrace);
-+		utrace = NULL;
-+	}
 +
 +	/*
 +	 * Now we're finished updating the utrace state.
 +	 * Do a pending self-reaping or parent notification.
 +	 */
++	if (exit_state == EXIT_ZOMBIE) {
++		do_notify_parent(tsk, tsk->exit_signal);
++
++		/*
++		 * If SIGCHLD was ignored, that set tsk->exit_signal = -1
++		 * to tell us to reap it immediately.
++		 */
++		if (tsk->exit_signal == -1) {
++			exit_state = xchg(&tsk->exit_state, EXIT_DEAD);
++			BUG_ON(exit_state != EXIT_ZOMBIE);
++			exit_state = EXIT_DEAD;	/* Reap it below.  */
++		}
++		read_unlock(&tasklist_lock); /* See comment above.  */
++	}
 +	if (exit_state == EXIT_DEAD)
 +		/*
 +		 * Note this can wind up in utrace_reap and do more callbacks.
 +		 * Our callers must be in places where that is OK.
 +		 */
 +		release_task(tsk);
-+	else if (exit_state == EXIT_ZOMBIE) {
-+		do_notify_parent(tsk, tsk->exit_signal);
-+		read_unlock(&tasklist_lock); /* See comment above.  */
-+	}
 +}
 +
 +
@@ -3700,12 +3722,19 @@
 +	rcu_read_lock();
 +	utrace = rcu_dereference(target->utrace);
 +	smp_rmb();
++	if (unlikely(target->exit_state == EXIT_DEAD)) {
++		/*
++		 * The target has already been reaped.
++		 * Check this first; a race with reaping may lead to restart.
++		 */
++		rcu_read_unlock();
++		return ERR_PTR(-ESRCH);
++	}
 +	if (utrace == NULL) {
 +		rcu_read_unlock();
 +
-+		if (!(flags & UTRACE_ATTACH_CREATE)) {
++		if (!(flags & UTRACE_ATTACH_CREATE))
 +			return ERR_PTR(-ENOENT);
-+		}
 +
 +		engine = kmem_cache_alloc(utrace_engine_cachep, GFP_KERNEL);
 +		if (unlikely(engine == NULL))
@@ -3714,19 +3743,12 @@
 +
 +	first:
 +		utrace = utrace_first_engine(target, engine);
-+		if (IS_ERR(utrace)) {
++		if (IS_ERR(utrace) || unlikely(utrace == NULL)) {
 +			kmem_cache_free(utrace_engine_cachep, engine);
++			if (unlikely(utrace == NULL)) /* Race condition.  */
++				goto restart;
 +			return ERR_PTR(PTR_ERR(utrace));
 +		}
-+		if (unlikely(utrace == NULL)) /* Race condition.  */
-+			goto restart;
-+	}
-+	else if (unlikely(target->exit_state == EXIT_DEAD)) {
-+		/*
-+		 * The target has already been reaped.
-+		 */
-+		rcu_read_unlock();
-+		return ERR_PTR(-ESRCH);
 +	}
 +	else {
 +		if (!(flags & UTRACE_ATTACH_CREATE)) {
@@ -5725,7 +5747,7 @@
  			goto out;
 --- linux-2.6/kernel/timer.c
 +++ linux-2.6/kernel/timer.c
-@@ -1326,9 +1326,9 @@ asmlinkage long sys_getpid(void)
+@@ -1335,9 +1335,9 @@ asmlinkage long sys_getpid(void)
  }
  
  /*
@@ -5737,7 +5759,7 @@
   * release_task()->call_rcu(delayed_put_task_struct).
   */
  asmlinkage long sys_getppid(void)
-@@ -1336,7 +1336,7 @@ asmlinkage long sys_getppid(void)
+@@ -1345,7 +1345,7 @@ asmlinkage long sys_getppid(void)
  	int pid;
  
  	rcu_read_lock();
@@ -5748,7 +5770,7 @@
  	return pid;
 --- linux-2.6/kernel/ptrace.c
 +++ linux-2.6/kernel/ptrace.c
-@@ -18,473 +18,1560 @@
+@@ -18,473 +18,1590 @@
  #include <linux/ptrace.h>
  #include <linux/security.h>
  #include <linux/signal.h>
@@ -5871,7 +5893,9 @@
  	}
 +	list_add_rcu(&state->entry, &state->parent->ptracees);
 +	task_unlock(state->parent);
-+
+ 
+-	if (child->state == TASK_TRACED)
+-		ptrace_untrace(child);
 +	BUG_ON(engine->data != 0);
 +	rcu_assign_pointer(engine->data, (unsigned long) state);
 +
@@ -5885,9 +5909,7 @@
 +						  struct ptrace_state, u.dead);
 +	kfree(state);
 +}
- 
--	if (child->state == TASK_TRACED)
--		ptrace_untrace(child);
++
 +static void
 +ptrace_done(struct ptrace_state *state)
 +{
@@ -5932,7 +5954,9 @@
 -	read_unlock(&tasklist_lock);
 +	flags |= (UTRACE_EVENT(DEATH) | UTRACE_EVENT(EXEC)
 +		  | UTRACE_EVENT_SIGNAL_ALL | UTRACE_EVENT(JCTL));
-+
+ 
+-	if (!ret && !kill) {
+-		wait_task_inactive(child);
 +	/*
 +	 * We always have to examine clone events to check for CLONE_PTRACE.
 +	 */
@@ -5951,9 +5975,7 @@
 +	 * But for a corner case we sometimes see the REAP event anyway.
 +	 */
 +	flags |= UTRACE_ACTION_NOREAP | UTRACE_EVENT(REAP);
- 
--	if (!ret && !kill) {
--		wait_task_inactive(child);
++
 +	if (!(flags & UTRACE_ACTION_QUIESCE)) {
 +		/*
 +		 * We're letting the thread resume from ptrace stop.
@@ -5968,10 +5990,19 @@
 +			state->u.live.u.siginfo = NULL;
 +
 +		if (target->state == TASK_STOPPED) {
-+			spin_lock_irq(&target->sighand->siglock);
-+			if (target->state == TASK_STOPPED)
-+				target->signal->flags &= ~SIGNAL_STOP_STOPPED;
-+			spin_unlock_irq(&target->sighand->siglock);
++			/*
++			 * We have to double-check for naughty de_thread
++			 * reaping despite NOREAP, before we can get siglock.
++			 */
++			read_lock(&tasklist_lock);
++			if (!target->exit_state) {
++				spin_lock_irq(&target->sighand->siglock);
++				if (target->state == TASK_STOPPED)
++					target->signal->flags &=
++						~SIGNAL_STOP_STOPPED;
++				spin_unlock_irq(&target->sighand->siglock);
++			}
++			read_unlock(&tasklist_lock);
 +		}
  	}
  
@@ -6098,7 +6129,8 @@
  	retval = -EPERM;
  	if (task->pid <= 1)
 -		goto out;
--	if (task->tgid == current->tgid)
++		goto bad;
+ 	if (task->tgid == current->tgid)
 -		goto out;
 -
 -repeat:
@@ -6126,20 +6158,11 @@
  		goto bad;
 -	/* the same process cannot be attached many times */
 -	if (task->ptrace & PT_PTRACED)
-+	if (task->tgid == current->tgid)
++	if (!task->mm)		/* kernel threads */
  		goto bad;
 -	retval = may_attach(task);
 -	if (retval)
-+	if (!task->mm)		/* kernel threads */
- 		goto bad;
- 
--	/* Go */
--	task->ptrace |= PT_PTRACED | ((task->real_parent != current)
--				      ? PT_ATTACHED : 0);
--	if (capable(CAP_SYS_PTRACE))
--		task->ptrace |= PT_PTRACE_CAP;
--
--	__ptrace_link(task, current);
++
 +	engine = utrace_attach(task, (UTRACE_ATTACH_CREATE
 +				      | UTRACE_ATTACH_EXCLUSIVE
 +				      | UTRACE_ATTACH_MATCH_OPS),
@@ -6148,10 +6171,14 @@
 +		retval = PTR_ERR(engine);
 +		if (retval == -EEXIST)
 +			retval = -EPERM;
-+		goto bad;
+ 		goto bad;
 +	}
  
--	force_sig_specific(SIGSTOP, task);
+-	/* Go */
+-	task->ptrace |= PT_PTRACED | ((task->real_parent != current)
+-				      ? PT_ATTACHED : 0);
+-	if (capable(CAP_SYS_PTRACE))
+-		task->ptrace |= PT_PTRACE_CAP;
 +	if (ptrace_may_attach(task)) {
 +		state = ptrace_setup(task, engine, current, 0,
 +				     capable(CAP_SYS_PTRACE), NULL);
@@ -6174,14 +6201,26 @@
 +	if (retval)
 +		(void) utrace_detach(task, engine);
 +	else {
-+		int stopped;
-+
-+		force_sig_specific(SIGSTOP, task);
-+
-+		spin_lock_irq(&task->sighand->siglock);
-+		stopped = (task->state == TASK_STOPPED);
-+		spin_unlock_irq(&task->sighand->siglock);
++		int stopped = 0;
+ 
+-	__ptrace_link(task, current);
++		/*
++		 * We must double-check that task has not just died and
++		 * been reaped (after ptrace_update succeeded).
++		 * This happens when exec (de_thread) ignores NOREAP.
++		 * We cannot call into the signal code if it's dead.
++		 */
++		read_lock(&tasklist_lock);
++		if (likely(!task->exit_state)) {
++			force_sig_specific(SIGSTOP, task);
 +
++			spin_lock_irq(&task->sighand->siglock);
++			stopped = (task->state == TASK_STOPPED);
++			spin_unlock_irq(&task->sighand->siglock);
++		}
++		read_unlock(&tasklist_lock);
+ 
+-	force_sig_specific(SIGSTOP, task);
 +		if (stopped) {
 +			/*
 +			 * Do now the regset 0 writeback that we do on every
@@ -6214,8 +6253,19 @@
 -	/* .. and wake it up. */
 -	if (child->exit_state != EXIT_ZOMBIE)
 -		wake_up_process(child);
-+	struct ptrace_state *state = (struct ptrace_state *) engine->data;
-+	int error = utrace_detach(task, engine);
++	struct ptrace_state *state;
++	int error;
++
++#ifdef HAVE_ARCH_PTRACE_DETACH
++	/*
++	 * Some funky compatibility code in arch_ptrace may have
++	 * needed to install special state it should clean up now.
++	 */
++	arch_ptrace_detach(task);
++#endif
++
++	state = (struct ptrace_state *) engine->data;
++	error = utrace_detach(task, engine);
 +	if (!error) {
 +		/*
 +		 * We can only get here from the ptracer itself or via
@@ -6239,17 +6289,15 @@
 +		spin_unlock_irq(&current->sighand->siglock);
 +	}
 +	return error;
- }
- 
--int ptrace_detach(struct task_struct *child, unsigned int data)
++}
++
 +
 +/*
 + * This is called when we are exiting.  We must stop all our ptracing.
 + */
 +void
 +ptrace_exit(struct task_struct *tsk)
- {
--	if (!valid_signal(data))
++{
 +	struct list_head *pos, *n;
 +
 +	/*
@@ -6298,13 +6346,15 @@
 +	rcu_read_unlock();
 +
 +	BUG_ON(!list_empty(&tsk->ptracees));
-+}
-+
+ }
+ 
+-int ptrace_detach(struct task_struct *child, unsigned int data)
 +static int
 +ptrace_induce_signal(struct task_struct *target,
 +		     struct utrace_attached_engine *engine,
 +		     long signr)
-+{
+ {
+-	if (!valid_signal(data))
 +	struct ptrace_state *state = (struct ptrace_state *) engine->data;
 +
 +	if (signr == 0)
@@ -6390,15 +6440,15 @@
 +		else
 +			ret = (*regset->set)(target, regset,
 +					     offset, size, NULL, data);
-+	}
+ 	}
+-	return copied;
 +	else {
 +		if (!access_ok(VERIFY_WRITE, data, size))
 +			ret = -EIO;
 +		else
 +			ret = (*regset->get)(target, regset,
 +					     offset, size, NULL, data);
- 	}
--	return copied;
++	}
 +
 +	return ret;
  }
@@ -6416,15 +6466,12 @@
 +							   view, setno);
 +	unsigned int pos;
 +	int ret;
-+
-+	if (unlikely(regset == NULL))
-+		return -EIO;
  
 -	while (len > 0) {
 -		char buf[128];
 -		int this_len, retval;
-+	if (regno < regset->bias || regno >= regset->bias + regset->n)
-+		return -EINVAL;
++	if (unlikely(regset == NULL))
++		return -EIO;
  
 -		this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
 -		if (copy_from_user(buf, src, this_len))
@@ -6439,6 +6486,9 @@
 -		src += retval;
 -		dst += retval;
 -		len -= retval;			
++	if (regno < regset->bias || regno >= regset->bias + regset->n)
++		return -EINVAL;
++
 +	pos = (regno - regset->bias) * regset->size;
 +
 +	if (write) {
@@ -6447,15 +6497,15 @@
 +		else
 +			ret = (*regset->set)(target, regset, pos, regset->size,
 +					     NULL, data);
-+	}
+ 	}
+-	return copied;
 +	else {
 +		if (!access_ok(VERIFY_WRITE, data, regset->size))
 +			ret = -EIO;
 +		else
 +			ret = (*regset->get)(target, regset, pos, regset->size,
 +					     NULL, data);
- 	}
--	return copied;
++	}
 +
 +	return ret;
  }
@@ -6570,10 +6620,10 @@
 +	struct utrace_attached_engine *engine;
 +	struct ptrace_state *state;
 +	int ret;
-+
+ 
 +	if (request == PTRACE_TRACEME)
 +		return ptrace_traceme();
- 
++
 +	ret = -ESRCH;
  	read_lock(&tasklist_lock);
 -	if (likely(child->sighand != NULL)) {
@@ -6779,7 +6829,7 @@
 +		if (ret)
 +			BUG_ON(ret != -ESRCH);
 +		ret = 0;
- 		break;
++		break;
 +	}
 +
 +	return ret;
@@ -6825,7 +6875,7 @@
 +		if (copied != sizeof(tmp))
 +			break;
 +		ret = put_user(tmp, (unsigned long __user *) data);
-+		break;
+ 		break;
 +	}
 +
 +	case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -6913,9 +6963,9 @@
 +		if (copied != sizeof(tmp))
 +			break;
 +		ret = put_user(tmp, (compat_ulong_t __user *) data);
-+		break;
-+	}
-+
+ 		break;
+ 	}
+ 
 +	case PTRACE_POKETEXT: /* write the word at location addr. */
 +	case PTRACE_POKEDATA:
 +		ret = 0;
@@ -6943,9 +6993,9 @@
 +			    state->u.live.u.siginfo,
 +			    (struct compat_siginfo __user *) data))
 +			ret = -EFAULT;
- 		break;
- 	}
- 
++		break;
++	}
++
 +out_tsk:
 +	put_task_struct(child);
 +out:
@@ -6953,13 +7003,13 @@
  	return ret;
  }
 +#endif
++
  
 -/**
 - * ptrace_traceme  --  helper for PTRACE_TRACEME
 - *
 - * Performs checks and sets PT_PTRACED.
 - * Should be used by all ptrace implementations for PTRACE_TRACEME.
-+
 +/*
 + * Detach the zombie being reported for wait.
   */
@@ -7254,19 +7304,15 @@
 +			info.si_status = tsk->exit_code >> 8;
 +		}
 +	}
- 
++
 +	sighand = parent->sighand;
 +	spin_lock_irqsave(&sighand->siglock, flags);
 +	if (sighand->action[SIGCHLD-1].sa.sa_handler != SIG_IGN &&
 +	    !(sighand->action[SIGCHLD-1].sa.sa_flags & sa_mask))
 +		__group_send_sig_info(SIGCHLD, &info, parent);
- 	/*
--	 * This lock_kernel fixes a subtle race with suid exec
++	/*
 +	 * Even if SIGCHLD is not generated, we must wake up wait4 calls.
- 	 */
--	lock_kernel();
--	if (request == PTRACE_TRACEME) {
--		ret = ptrace_traceme();
++	 */
 +	wake_up_interruptible_sync(&parent->signal->wait_chldexit);
 +	spin_unlock_irqrestore(&sighand->siglock, flags);
 +}
@@ -7297,13 +7343,17 @@
 +	 * try to resume us with PTRACE_CONT before we set the flag.
 +	 */
 +	utrace_set_flags(tsk, engine, engine->flags | UTRACE_ACTION_QUIESCE);
-+
-+	/*
+ 
+ 	/*
+-	 * This lock_kernel fixes a subtle race with suid exec
 +	 * If regset 0 has a writeback call, do it now.  On register window
 +	 * machines, this makes sure the user memory backing the register
 +	 * data is up to date by the time wait_task_inactive returns to
 +	 * ptrace_start in our tracer doing a PTRACE_PEEKDATA or the like.
-+	 */
+ 	 */
+-	lock_kernel();
+-	if (request == PTRACE_TRACEME) {
+-		ret = ptrace_traceme();
 +	regset = utrace_regset(tsk, engine, utrace_native_view(tsk), 0);
 +	if (regset->writeback)
 +		(*regset->writeback)(tsk, regset, 0);
@@ -7515,8 +7565,7 @@
 +		 tsk->pid, state->parent->pid, type, tsk->exit_code);
 +	do_notify(tsk, state->parent, type);
 +	return UTRACE_JCTL_NOSIGCHLD;
- }
--#endif /* __ARCH_SYS_PTRACE */
++}
 +
 +static u32
 +ptrace_report_exec(struct utrace_attached_engine *engine,
@@ -7559,7 +7608,8 @@
 +			    struct task_struct *tsk, struct pt_regs *regs)
 +{
 +	return ptrace_report_syscall(engine, tsk, regs, 0);
-+}
+ }
+-#endif /* __ARCH_SYS_PTRACE */
 +
 +static u32
 +ptrace_report_exit(struct utrace_attached_engine *engine,
@@ -7925,7 +7975,7 @@
  
 --- linux-2.6/init/Kconfig
 +++ linux-2.6/init/Kconfig
-@@ -579,6 +579,35 @@ config STOP_MACHINE
+@@ -595,6 +595,35 @@ config STOP_MACHINE
  	  Need stop_machine() primitive.
  endmenu
  
@@ -8320,7 +8370,7 @@
  	current->thread.error_code = error_code;
 --- linux-2.6/arch/i386/kernel/process.c
 +++ linux-2.6/arch/i386/kernel/process.c
-@@ -820,9 +820,6 @@ asmlinkage int sys_execve(struct pt_regs
+@@ -769,9 +769,6 @@ asmlinkage int sys_execve(struct pt_regs
  			(char __user * __user *) regs.edx,
  			&regs);
  	if (error == 0) {
@@ -8812,7 +8862,7 @@
  
  	return 0;
  }
-@@ -326,308 +615,155 @@ ptrace_get_thread_area(struct task_struc
+@@ -326,308 +615,154 @@ ptrace_get_thread_area(struct task_struc
   * Perform set_thread_area on behalf of the traced child.
   */
  static int
@@ -9190,8 +9240,7 @@
 +
 +const struct utrace_regset_view utrace_i386_native = {
 +	.name = "i386", .e_machine = EM_386,
-+	.regsets = native_regsets,
-+	.n = sizeof native_regsets / sizeof native_regsets[0],
++	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_i386_native);
 +
@@ -9251,7 +9300,7 @@
  
  void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
  {
-@@ -651,78 +787,24 @@ void send_sigtrap(struct task_struct *ts
+@@ -651,78 +786,24 @@ void send_sigtrap(struct task_struct *ts
   * - triggered by current->work.syscall_trace
   */
  __attribute__((regparm(3)))
@@ -9413,7 +9462,7 @@
  }
 --- linux-2.6/arch/mips/kernel/ptrace.c
 +++ linux-2.6/arch/mips/kernel/ptrace.c
-@@ -477,26 +477,9 @@ asmlinkage void do_syscall_trace(struct 
+@@ -487,26 +487,9 @@ asmlinkage void do_syscall_trace(struct 
  		audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]),
  		                   regs->regs[2]);
  
@@ -10511,7 +10560,7 @@
  /*
   * For get_evrregs/set_evrregs functions 'data' has the following layout:
   *
-@@ -154,383 +265,454 @@ static inline int set_vrregs(struct task
+@@ -154,383 +265,452 @@ static inline int set_vrregs(struct task
   * }
   */
  
@@ -10616,8 +10665,7 @@
 +
 +const struct utrace_regset_view utrace_ppc_native_view = {
 +	.name = UTS_MACHINE, .e_machine = ELF_ARCH,
-+	.regsets = native_regsets,
-+	.n = sizeof native_regsets / sizeof native_regsets[0],
++	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_ppc_native_view);
  
@@ -10794,8 +10842,7 @@
 +
 +const struct utrace_regset_view utrace_ppc32_view = {
 +	.name = "ppc", .e_machine = EM_PPC,
-+	.regsets = ppc32_regsets,
-+	.n = sizeof ppc32_regsets / sizeof ppc32_regsets[0],
++	.regsets = ppc32_regsets, .n = ARRAY_SIZE(ppc32_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_ppc32_view);
 +#endif
@@ -11273,7 +11320,7 @@
  
  	if (unlikely(current->audit_context)) {
  #ifdef CONFIG_PPC64
-@@ -556,8 +738,11 @@ void do_syscall_trace_leave(struct pt_re
+@@ -556,8 +736,11 @@ void do_syscall_trace_leave(struct pt_re
  		audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
  				   regs->result);
  
@@ -11416,7 +11463,7 @@
   * Copyright (C) 1997 Jakub Jelinek (jj at sunsite.mff.cuni.cz)
   *
   * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
-@@ -11,103 +11,597 @@
+@@ -11,103 +11,595 @@
   */
  
  #include <linux/kernel.h>
@@ -11734,8 +11781,7 @@
 -void ptrace_disable(struct task_struct *child)
 +const struct utrace_regset_view utrace_sparc64_native_view = {
 +	.name = UTS_MACHINE, .e_machine = ELF_ARCH,
-+	.regsets = native_regsets,
-+	.n = sizeof native_regsets / sizeof native_regsets[0],
++	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_sparc64_native_view);
 +
@@ -12074,8 +12120,7 @@
 +
 +const struct utrace_regset_view utrace_sparc32_view = {
 +	.name = "sparc", .e_machine = EM_SPARC,
-+	.regsets = sparc32_regsets,
-+	.n = sizeof sparc32_regsets / sizeof sparc32_regsets[0],
++	.regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_sparc32_view);
 +
@@ -12084,7 +12129,7 @@
  /* To get the necessary page struct, access_process_vm() first calls
   * get_user_pages().  This has done a flush_dcache_page() on the
   * accessed page.  Then our caller (copy_{to,from}_user_page()) did
-@@ -167,487 +661,124 @@ void flush_ptrace_access(struct vm_area_
+@@ -167,487 +659,124 @@ void flush_ptrace_access(struct vm_area_
  	}
  }
  
@@ -12673,7 +12718,7 @@
  
  	if (unlikely(current->audit_context) && syscall_exit_p) {
  		unsigned long tstate = regs->tstate;
-@@ -659,26 +790,9 @@ asmlinkage void syscall_trace(struct pt_
+@@ -659,26 +788,9 @@ asmlinkage void syscall_trace(struct pt_
  		audit_syscall_exit(result, regs->u_regs[UREG_I0]);
  	}
  
@@ -13416,7 +13461,7 @@
  	}
  	if (write_access)
  		*ptr = *data;
-@@ -1104,567 +845,827 @@ access_uarea (struct task_struct *child,
+@@ -1104,567 +845,826 @@ access_uarea (struct task_struct *child,
  	return 0;
  }
  
@@ -14606,8 +14651,7 @@
 +const struct utrace_regset_view utrace_ia64_native = {
 +	.name = "ia64",
 +	.e_machine = EM_IA_64,
-+	.regsets = native_regsets,
-+	.n = sizeof native_regsets / sizeof native_regsets[0],
++	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_ia64_native);
 +
@@ -14759,7 +14803,7 @@
  #include <linux/stat.h>
  #include <linux/ipc.h>
  #include <linux/capability.h>
-@@ -1432,25 +1433,6 @@ sys32_waitpid (int pid, unsigned int *st
+@@ -1436,25 +1437,6 @@ sys32_waitpid (int pid, unsigned int *st
  	return compat_sys_wait4(pid, stat_addr, options, NULL);
  }
  
@@ -14785,7 +14829,7 @@
  /*
   *  The order in which registers are stored in the ptrace regs structure
   */
-@@ -1748,6 +1730,7 @@ restore_ia32_fpxstate (struct task_struc
+@@ -1752,6 +1734,7 @@ restore_ia32_fpxstate (struct task_struc
  	return 0;
  }
  
@@ -14793,7 +14837,7 @@
  asmlinkage long
  sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
  {
-@@ -1855,9 +1838,11 @@ sys32_ptrace (int request, pid_t pid, un
+@@ -1859,9 +1842,11 @@ sys32_ptrace (int request, pid_t pid, un
  					    compat_ptr(data));
  		break;
  
@@ -14805,7 +14849,7 @@
  
  	      case PTRACE_SYSCALL:	/* continue, stop after next syscall */
  	      case PTRACE_CONT:		/* restart after signal. */
-@@ -1878,6 +1863,520 @@ sys32_ptrace (int request, pid_t pid, un
+@@ -1882,6 +1867,519 @@ sys32_ptrace (int request, pid_t pid, un
  	unlock_kernel();
  	return ret;
  }
@@ -14916,7 +14960,7 @@
 +	if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
 +		pt = task_pt_regs(task);
 +		tos = (task->thread.fsr >> 11) & 7;
-+		end = min(dst->pos + dst->count, 
++		end = min(dst->pos + dst->count,
 +				(unsigned int)(sizeof(struct ia32_user_i387_struct)));
 +		start = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
 +		end = (end - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
@@ -15080,12 +15124,12 @@
 +	if (dst->pos < OFFSET(xmm_space[0])) {
 +		pt = task_pt_regs(task);
 +		tos = (task->thread.fsr >> 11) & 7;
-+		end = min(dst->pos + dst->count, 
++		end = min(dst->pos + dst->count,
 +				(unsigned int)OFFSET(xmm_space[0]));
 +		start = (dst->pos - OFFSET(st_space[0])) / 16;
 +		end = (end - OFFSET(st_space[0])) / 16;
 +		for (; start < end; start++)
-+			access_fpreg_ia32(start, buf + 16 * start, pt, 
++			access_fpreg_ia32(start, buf + 16 * start, pt,
 +						info->sw, tos, 0);
 +		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
 +				&dst->u.get.kbuf, &dst->u.get.ubuf,
@@ -15278,8 +15322,7 @@
 +
 +const struct utrace_regset_view utrace_ia32_view = {
 +	.name = "i386", .e_machine = EM_386,
-+	.regsets = ia32_regsets,
-+	.n = sizeof ia32_regsets / sizeof ia32_regsets[0],
++	.regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_ia32_view);
 +#endif
@@ -15456,7 +15499,7 @@
  
  #ifdef CONFIG_COMPAT
  #include "compat_ptrace.h"
-@@ -84,653 +87,639 @@ FixPerRegisters(struct task_struct *task
+@@ -84,653 +87,637 @@ FixPerRegisters(struct task_struct *task
  		per_info->control_regs.bits.storage_alt_space_ctl = 1;
  	else
  		per_info->control_regs.bits.storage_alt_space_ctl = 0;
@@ -15938,8 +15981,7 @@
 +
 +const struct utrace_regset_view utrace_s390_native_view = {
 +	.name = UTS_MACHINE, .e_machine = ELF_ARCH,
-+	.regsets = native_regsets,
-+	.n = sizeof native_regsets / sizeof native_regsets[0],
++	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_s390_native_view);
  
@@ -16315,8 +16357,7 @@
 +
 +const struct utrace_regset_view utrace_s390_compat_view = {
 +	.name = "s390", .e_machine = EM_S390,
-+	.regsets = s390_compat_regsets,
-+	.n = sizeof s390_compat_regsets / sizeof s390_compat_regsets[0],
++	.regsets = s390_compat_regsets, .n = ARRAY_SIZE(s390_compat_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_s390_compat_view);
 +#endif	/* CONFIG_COMPAT */
@@ -16646,7 +16687,7 @@
  
  asmlinkage void
  syscall_trace(struct pt_regs *regs, int entryexit)
-@@ -738,30 +727,17 @@ syscall_trace(struct pt_regs *regs, int 
+@@ -738,30 +725,17 @@ syscall_trace(struct pt_regs *regs, int 
  	if (unlikely(current->audit_context) && entryexit)
  		audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
  
@@ -16869,7 +16910,7 @@
  			break;
  		case offsetof(struct user_regs_struct,cs): 
  			if ((value & 3) != 3)
-@@ -301,311 +304,438 @@ static unsigned long getreg(struct task_
+@@ -301,311 +304,435 @@ static unsigned long getreg(struct task_
  			val = get_stack_long(child, regno);
  			if (test_tsk_thread_flag(child, TIF_IA32))
  				val &= 0xffffffff;
@@ -17486,8 +17527,7 @@
 +
 +const struct utrace_regset_view utrace_x86_64_native = {
 +	.name = "x86-64", .e_machine = EM_X86_64,
-+	.regsets = native_regsets,
-+	.n = sizeof native_regsets / sizeof native_regsets[0],
++	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_x86_64_native);
 +
@@ -17498,9 +17538,7 @@
 +	{sizeof(struct user_regs_struct),
 +	 offsetof(struct user, u_debugreg[0]), -1, 0},
 +	{offsetof(struct user, u_debugreg[0]),
-+	 offsetof(struct user, u_debugreg[4]), 3, 0},
-+	{offsetof(struct user, u_debugreg[6]),
-+	 offsetof(struct user, u_debugreg[8]), 3, 6 * sizeof(long)},
++	 offsetof(struct user, u_debugreg[8]), 3, 0},
 +	{0, 0, -1, 0}
 +};
 +
@@ -17564,7 +17602,7 @@
  
  	if (unlikely(current->audit_context)) {
  		if (test_thread_flag(TIF_IA32)) {
-@@ -627,8 +757,11 @@ asmlinkage void syscall_trace_leave(stru
+@@ -627,8 +754,11 @@ asmlinkage void syscall_trace_leave(stru
  	if (unlikely(current->audit_context))
  		audit_syscall_exit(AUDITSC_RESULT(regs->rax), regs->rax);
  
@@ -17743,7 +17781,7 @@
  		break;
  
  	R32(cs, cs);
-@@ -167,236 +131,505 @@ static int getreg32(struct task_struct *
+@@ -167,236 +131,504 @@ static int getreg32(struct task_struct *
  	R32(eax, rax);
  	R32(orig_eax, orig_rax);
  	R32(eip, rip);
@@ -18377,8 +18415,7 @@
 +
 +const struct utrace_regset_view utrace_ia32_view = {
 +	.name = "i386", .e_machine = EM_386,
-+	.regsets = ia32_regsets,
-+	.n = sizeof ia32_regsets / sizeof ia32_regsets[0],
++	.regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
 +};
 +EXPORT_SYMBOL_GPL(utrace_ia32_view);
 +




More information about the fedora-cvs-commits mailing list