rpms/kernel/devel linux-2.6-powerpc-tracehook.patch, NONE, 1.1 linux-2.6-sparc64-tracehook.patch, NONE, 1.1 linux-2.6-x86-tracehook.patch, NONE, 1.1 patch-2.6.26-git11.bz2.sign, NONE, 1.1 .cvsignore, 1.875, 1.876 config-ia64-generic, 1.14, 1.15 kernel.spec, 1.792, 1.793 linux-2.6-tracehook.patch, 1.4, 1.5 linux-2.6-utrace.patch, 1.82, 1.83 sources, 1.836, 1.837 upstream, 1.753, 1.754 linux-2.6-ptrace-cleanup.patch, 1.3, NONE patch-2.6.26-git10.bz2.sign, 1.1, NONE

Roland McGrath (roland) fedora-extras-commits at redhat.com
Thu Jul 24 08:29:12 UTC 2008


Author: roland

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv18822

Modified Files:
	.cvsignore config-ia64-generic kernel.spec 
	linux-2.6-tracehook.patch linux-2.6-utrace.patch sources 
	upstream 
Added Files:
	linux-2.6-powerpc-tracehook.patch 
	linux-2.6-sparc64-tracehook.patch 
	linux-2.6-x86-tracehook.patch patch-2.6.26-git11.bz2.sign 
Removed Files:
	linux-2.6-ptrace-cleanup.patch patch-2.6.26-git10.bz2.sign 
Log Message:
* Thu Jul 24 2008 Roland McGrath <roland at redhat.com>
- 2.6.26-git11
- utrace update


linux-2.6-powerpc-tracehook.patch:

--- NEW FILE linux-2.6-powerpc-tracehook.patch ---
 arch/powerpc/Kconfig              |    1 +
 arch/powerpc/kernel/entry_32.S    |   11 ++++-
 arch/powerpc/kernel/entry_64.S    |   10 +++-
 arch/powerpc/kernel/ptrace.c      |   66 +++++++++++++++++-----------
 arch/powerpc/kernel/signal.c      |   21 ++++++++-
 include/asm-powerpc/ptrace.h      |    5 ++
 include/asm-powerpc/signal.h      |    3 +-
 include/asm-powerpc/syscall.h     |   84 +++++++++++++++++++++++++++++++++++++
 include/asm-powerpc/thread_info.h |    5 ++-
 9 files changed, 169 insertions(+), 37 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 737ebf9..8f2c5c7 100644  
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -114,6 +114,7 @@ config PPC
 	select HAVE_KPROBES
 	select HAVE_ARCH_KGDB
 	select HAVE_KRETPROBES
+	select HAVE_ARCH_TRACEHOOK
 	select HAVE_LMB
 	select HAVE_DMA_ATTRS if PPC64
 	select USE_GENERIC_SMP_HELPERS if SMP
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index da52269..1cbbf70 100644  
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -343,7 +343,12 @@ syscall_dotrace:
 	stw	r0,_TRAP(r1)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	do_syscall_trace_enter
-	lwz	r0,GPR0(r1)	/* Restore original registers */
+	/*
+	 * Restore argument registers possibly just changed.
+	 * We use the return value of do_syscall_trace_enter
+	 * for call number to look up in the table (r0).
+	 */
+	mr	r0,r3
 	lwz	r3,GPR3(r1)
 	lwz	r4,GPR4(r1)
 	lwz	r5,GPR5(r1)
@@ -1055,8 +1060,8 @@ do_user_signal:			/* r10 contains MSR_KE
 	SAVE_NVGPRS(r1)
 	rlwinm	r3,r3,0,0,30
 	stw	r3,_TRAP(r1)
-2:	li	r3,0
-	addi	r4,r1,STACK_FRAME_OVERHEAD
+2:	addi	r3,r1,STACK_FRAME_OVERHEAD
+	mr	r4,r9
 	bl	do_signal
 	REST_NVGPRS(r1)
 	b	recheck
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index d736924..2d802e9 100644  
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -214,7 +214,12 @@ syscall_dotrace:
 	bl	.save_nvgprs
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_syscall_trace_enter
-	ld	r0,GPR0(r1)	/* Restore original registers */
+	/*
+	 * Restore argument registers possibly just changed.
+	 * We use the return value of do_syscall_trace_enter
+	 * for the call number to look up in the table (r0).
+	 */
+	mr	r0,r3
 	ld	r3,GPR3(r1)
 	ld	r4,GPR4(r1)
 	ld	r5,GPR5(r1)
@@ -638,8 +643,7 @@ user_work:
 	b	.ret_from_except_lite
 
 1:	bl	.save_nvgprs
-	li	r3,0
-	addi	r4,r1,STACK_FRAME_OVERHEAD
+	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_signal
 	b	.ret_from_except
 
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 8feb93e..a704603 100644  
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -22,6 +22,7 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/regset.h>
+#include <linux/tracehook.h>
 #include <linux/elf.h>
 #include <linux/user.h>
 #include <linux/security.h>
@@ -706,12 +707,29 @@ void user_enable_single_step(struct task
 		task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC;
 		regs->msr |= MSR_DE;
 #else
+		regs->msr &= ~MSR_BE;
 		regs->msr |= MSR_SE;
 #endif
 	}
 	set_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 
+void user_enable_block_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+
+	if (regs != NULL) {
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+		task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT;
+		regs->msr |= MSR_DE;
+#else
+		regs->msr &= ~MSR_SE;
+		regs->msr |= MSR_BE;
+#endif
+	}
+	set_tsk_thread_flag(task, TIF_SINGLESTEP);
+}
+
 void user_disable_single_step(struct task_struct *task)
 {
 	struct pt_regs *regs = task->thread.regs;
@@ -721,7 +739,7 @@ void user_disable_single_step(struct tas
 		task->thread.dbcr0 = 0;
 		regs->msr &= ~MSR_DE;
 #else
-		regs->msr &= ~MSR_SE;
+		regs->msr &= ~(MSR_SE | MSR_BE);
 #endif
 	}
 	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
@@ -953,31 +971,24 @@ long arch_ptrace(struct task_struct *chi
 	return ret;
 }
 
-static void do_syscall_trace(void)
+/*
+ * We must return the syscall number to actually look up in the table.
+ * This can be -1L to skip running any syscall at all.
+ */
+long do_syscall_trace_enter(struct pt_regs *regs)
 {
-	/* the 0x80 provides a way for the tracing parent to distinguish
-	   between a syscall stop and SIGTRAP delivery */
-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-				 ? 0x80 : 0));
-
-	/*
-	 * this isn't the same as continuing with a signal, but it will do
-	 * for normal use.  strace only continues with a signal if the
-	 * stopping signal is not SIGTRAP.  -brl
-	 */
-	if (current->exit_code) {
-		send_sig(current->exit_code, current, 1);
-		current->exit_code = 0;
-	}
-}
+	long ret = 0;
 
-void do_syscall_trace_enter(struct pt_regs *regs)
-{
 	secure_computing(regs->gpr[0]);
 
-	if (test_thread_flag(TIF_SYSCALL_TRACE)
-	    && (current->ptrace & PT_PTRACED))
-		do_syscall_trace();
+	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+	    tracehook_report_syscall_entry(regs))
+		/*
+		 * Tracing decided this syscall should not happen.
+		 * We'll return a bogus call number to get an ENOSYS
+		 * error, but leave the original number in regs->gpr[0].
+		 */
+		ret = -1L;
 
 	if (unlikely(current->audit_context)) {
 #ifdef CONFIG_PPC64
@@ -995,16 +1006,19 @@ void do_syscall_trace_enter(struct pt_re
 					    regs->gpr[5] & 0xffffffff,
 					    regs->gpr[6] & 0xffffffff);
 	}
+
+	return ret ?: regs->gpr[0];
 }
 
 void do_syscall_trace_leave(struct pt_regs *regs)
 {
+	int step;
+
 	if (unlikely(current->audit_context))
 		audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
 				   regs->result);
 
-	if ((test_thread_flag(TIF_SYSCALL_TRACE)
-	     || test_thread_flag(TIF_SINGLESTEP))
-	    && (current->ptrace & PT_PTRACED))
-		do_syscall_trace();
+	step = test_thread_flag(TIF_SINGLESTEP);
+	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
+		tracehook_report_syscall_exit(regs, step);
 }
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index ad55488..e032336 100644  
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -9,7 +9,7 @@
  * this archive for more details.
  */
 
-#include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/signal.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -112,7 +112,7 @@ static void check_syscall_restart(struct
 	}
 }
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs)
+static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
 {
 	siginfo_t info;
 	int signr;
@@ -173,11 +173,28 @@ int do_signal(sigset_t *oldset, struct p
 		 * its frame, and we can clear the TLF_RESTORE_SIGMASK flag.
 		 */
 		current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK;
+
+		/*
+		 * Let tracing know that we've done the handler setup.
+		 */
+		tracehook_signal_handler(signr, &info, &ka, regs,
+					 test_thread_flag(TIF_SINGLESTEP));
 	}
 
 	return ret;
 }
 
+void do_signal(struct pt_regs *regs, unsigned long thread_info_flags)
+{
+	if (thread_info_flags & _TIF_SIGPENDING)
+		do_signal_pending(NULL, regs);
+
+	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+		clear_thread_flag(TIF_NOTIFY_RESUME);
+		tracehook_notify_resume(regs);
+	}
+}
+
 long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
 		unsigned long r5, unsigned long r6, unsigned long r7,
 		unsigned long r8, struct pt_regs *regs)
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index 3d6e310..42301cf 100644  
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -84,6 +84,7 @@ struct pt_regs {
 #ifndef __ASSEMBLY__
 
 #define instruction_pointer(regs) ((regs)->nip)
+#define user_stack_pointer(regs) ((regs)->gpr[1])
 #define regs_return_value(regs) ((regs)->gpr[3])
 
 #ifdef CONFIG_SMP
@@ -136,7 +137,9 @@ do {									      \
  * These are defined as per linux/ptrace.h, which see.
  */
 #define arch_has_single_step()	(1)
+#define arch_has_block_step()	(1)
 extern void user_enable_single_step(struct task_struct *);
+extern void user_enable_block_step(struct task_struct *);
 extern void user_disable_single_step(struct task_struct *);
 
 #endif /* __ASSEMBLY__ */
@@ -289,4 +292,6 @@ extern void user_disable_single_step(str
 #define PPC_PTRACE_PEEKUSR_3264  0x91
 #define PPC_PTRACE_POKEUSR_3264  0x90
 
+#define PTRACE_SINGLEBLOCK	0x100	/* resume execution until next branch */
+
 #endif /* _ASM_POWERPC_PTRACE_H */
diff --git a/include/asm-powerpc/signal.h b/include/asm-powerpc/signal.h
index a8c7bab..a7360cd 100644  
--- a/include/asm-powerpc/signal.h
+++ b/include/asm-powerpc/signal.h
@@ -122,8 +122,7 @@ typedef struct sigaltstack {
 
 #ifdef __KERNEL__
 struct pt_regs;
-extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags);
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-powerpc/syscall.h b/include/asm-powerpc/syscall.h
new file mode 100644
index ...3ced23a 100644  
--- /dev/null
+++ b/include/asm-powerpc/syscall.h
@@ -0,0 +1,84 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * See asm-generic/syscall.h for descriptions of what we must do here.
+ */
+
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H	1
+
+#include <linux/sched.h>
+
+static inline long syscall_get_nr(struct task_struct *task,
+				  struct pt_regs *regs)
+{
+	return regs->trap == 0xc01 ? regs->gpr[0] : -1L;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+				    struct pt_regs *regs)
+{
+	regs->gpr[3] = regs->orig_gpr3;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+				     struct pt_regs *regs)
+{
+	return (regs->ccr & 0x1000) ? -regs->gpr[3] : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+					    struct pt_regs *regs)
+{
+	return regs->gpr[3];
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+					    struct pt_regs *regs,
+					    int error, long val)
+{
+	if (error) {
+		regs->ccr |= 0x1000L;
+		regs->gpr[3] = -error;
+	} else {
+		regs->ccr &= ~0x1000L;
+		regs->gpr[3] = val;
+	}
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+					 struct pt_regs *regs,
+					 unsigned int i, unsigned int n,
+					 unsigned long *args)
+{
+	BUG_ON(i + n > 6);
+#ifdef CONFIG_PPC64
+	if (test_tsk_thread_flag(task, TIF_32BIT)) {
+		/*
+		 * Zero-extend 32-bit argument values.  The high bits are
+		 * garbage ignored by the actual syscall dispatch.
+		 */
+		while (n-- > 0)
+			args[n] = (u32) regs->gpr[3 + i + n];
+		return;
+	}
+#endif
+	memcpy(args, &regs->gpr[3 + i], n * sizeof(args[0]));
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+					 struct pt_regs *regs,
+					 unsigned int i, unsigned int n,
+					 const unsigned long *args)
+{
+	BUG_ON(i + n > 6);
+	memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0]));
+}
+
+#endif	/* _ASM_SYSCALL_H */
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index b705c2a..a52d62e 100644  
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -116,6 +116,7 @@ static inline struct thread_info *curren
 #define TIF_SECCOMP		10	/* secure computing */
 #define TIF_RESTOREALL		11	/* Restore all regs (implies NOERROR) */
 #define TIF_NOERROR		12	/* Force successful syscall return */
+#define TIF_NOTIFY_RESUME	13	/* callback before returning to user */
 #define TIF_FREEZE		14	/* Freezing for suspend */
 #define TIF_RUNLATCH		15	/* Is the runlatch enabled? */
 #define TIF_ABI_PENDING		16	/* 32/64 bit switch needed */
@@ -133,12 +134,14 @@ static inline struct thread_info *curren
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_RESTOREALL		(1<<TIF_RESTOREALL)
 #define _TIF_NOERROR		(1<<TIF_NOERROR)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_FREEZE		(1<<TIF_FREEZE)
 #define _TIF_RUNLATCH		(1<<TIF_RUNLATCH)
 #define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
 #define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
 
-#define _TIF_USER_WORK_MASK	(_TIF_SIGPENDING | _TIF_NEED_RESCHED)
+#define _TIF_USER_WORK_MASK	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+				 _TIF_NOTIFY_RESUME)
 #define _TIF_PERSYSCALL_MASK	(_TIF_RESTOREALL|_TIF_NOERROR)
 
 /* Bits in local_flags */

linux-2.6-sparc64-tracehook.patch:

--- NEW FILE linux-2.6-sparc64-tracehook.patch ---
 arch/sparc64/Kconfig               |    1 +
 arch/sparc64/kernel/ptrace.c       |   24 +++--------
 arch/sparc64/kernel/rtrap.S        |    6 +-
 arch/sparc64/kernel/signal.c       |    7 +++
 arch/sparc64/kernel/signal32.c     |    2 +
 include/asm-sparc/ptrace_32.h      |    1 +
 include/asm-sparc/ptrace_64.h      |    1 +
 include/asm-sparc/syscall.h        |   79 ++++++++++++++++++++++++++++++++++++
 include/asm-sparc/thread_info_64.h |    8 ++-
 include/asm-sparc64/syscall.h      |    1 +
 10 files changed, 106 insertions(+), 24 deletions(-)

diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 7c88263..923a989 100644  
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -17,6 +17,7 @@ config SPARC64
 	select HAVE_LMB
 	select HAVE_ARCH_KGDB
 	select USE_GENERIC_SMP_HELPERS if SMP
+	select HAVE_ARCH_TRACEHOOK
 
 config GENERIC_TIME
 	bool
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index f6c9fc9..2e3f998 100644  
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -23,6 +23,7 @@
 #include <linux/audit.h>
 #include <linux/signal.h>
 #include <linux/regset.h>
+#include <linux/tracehook.h>
 #include <linux/compat.h>
 #include <linux/elf.h>
 
@@ -1064,26 +1065,13 @@ asmlinkage void syscall_trace(struct pt_
 		audit_syscall_exit(result, regs->u_regs[UREG_I0]);
 	}
 
-	if (!(current->ptrace & PT_PTRACED))
-		goto out;
-
-	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		goto out;
-
-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-				 ? 0x80 : 0));
-
-	/*
-	 * this isn't the same as continuing with a signal, but it will do
-	 * for normal use.  strace only continues with a signal if the
-	 * stopping signal is not SIGTRAP.  -brl
-	 */
-	if (current->exit_code) {
-		send_sig(current->exit_code, current, 1);
-		current->exit_code = 0;
+	if (test_thread_flag(TIF_SYSCALL_TRACE)) {
+		if (syscall_exit_p)
+			tracehook_report_syscall_exit(regs, 0);
+		else
+			tracehook_report_syscall_entry(regs);
 	}
 
-out:
 	if (unlikely(current->audit_context) && !syscall_exit_p)
 		audit_syscall_entry((test_thread_flag(TIF_32BIT) ?
 				     AUDIT_ARCH_SPARC :
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index c6fc695..97a993c 100644  
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -46,7 +46,7 @@ __handle_user_windows:
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		ldx			[%g6 + TI_FLAGS], %l0
 
-1:		andcc			%l0, _TIF_SIGPENDING, %g0
+1:		andcc			%l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
 		be,pt			%xcc, __handle_user_windows_continue
 		 nop
 		mov			%l5, %o1
@@ -86,7 +86,7 @@ __handle_perfctrs:
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
 		ldx			[%g6 + TI_FLAGS], %l0
-1:		andcc			%l0, _TIF_SIGPENDING, %g0
+1:		andcc			%l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
 
 		be,pt			%xcc, __handle_perfctrs_continue
 		 sethi			%hi(TSTATE_PEF), %o0
@@ -195,7 +195,7 @@ __handle_preemption_continue:
 		 andcc			%l1, %o0, %g0
 		andcc			%l0, _TIF_NEED_RESCHED, %g0
 		bne,pn			%xcc, __handle_preemption
-		 andcc			%l0, _TIF_SIGPENDING, %g0
+		 andcc			%l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
 		bne,pn			%xcc, __handle_signal
 __handle_signal_continue:
 		 ldub			[%g6 + TI_WSAVED], %o2
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 9667e96..e12bece 100644  
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/unistd.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
@@ -574,6 +575,8 @@ static void do_signal(struct pt_regs *re
 		 * clear the TS_RESTORE_SIGMASK flag.
 		 */
 		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+
+		tracehook_signal_handler(signr, &info, &ka, regs, 0);
 		return;
 	}
 	if (restart_syscall &&
@@ -605,4 +608,8 @@ void do_notify_resume(struct pt_regs *re
 {
 	if (thread_info_flags & _TIF_SIGPENDING)
 		do_signal(regs, orig_i0);
+	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+		clear_thread_flag(TIF_NOTIFY_RESUME);
+		tracehook_notify_resume(regs);
+	}
 }
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 97cdd1b..fb201b2 100644  
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -794,6 +794,8 @@ void do_signal32(sigset_t *oldset, struc
 		 * clear the TS_RESTORE_SIGMASK flag.
 		 */
 		current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+
+		tracehook_signal_handler(signr, &info, &ka, regs, 0);
 		return;
 	}
 	if (restart_syscall &&
diff --git a/include/asm-sparc/ptrace_32.h b/include/asm-sparc/ptrace_32.h
index 0401cc7..d43c88b 100644  
--- a/include/asm-sparc/ptrace_32.h
+++ b/include/asm-sparc/ptrace_32.h
@@ -74,6 +74,7 @@ struct sparc_stackf {
 
 #define user_mode(regs) (!((regs)->psr & PSR_PS))
 #define instruction_pointer(regs) ((regs)->pc)
+#define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
 unsigned long profile_pc(struct pt_regs *);
 extern void show_regs(struct pt_regs *);
 #endif
diff --git a/include/asm-sparc/ptrace_64.h b/include/asm-sparc/ptrace_64.h
index a682e66..ec6d45c 100644  
--- a/include/asm-sparc/ptrace_64.h
+++ b/include/asm-sparc/ptrace_64.h
@@ -146,6 +146,7 @@ do {	current_thread_info()->syscall_noer
 } while (0)
 #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
 #define instruction_pointer(regs) ((regs)->tpc)
+#define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
 #define regs_return_value(regs) ((regs)->u_regs[UREG_I0])
 #ifdef CONFIG_SMP
 extern unsigned long profile_pc(struct pt_regs *);
diff --git a/include/asm-sparc/syscall.h b/include/asm-sparc/syscall.h
new file mode 100644
index ...53bf5b3 100644  
--- /dev/null
+++ b/include/asm-sparc/syscall.h
@@ -0,0 +1,79 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * See asm-generic/syscall.h for descriptions of what we must do here.
+ */
+
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H	1
+
+#include <linux/thread_info.h>
+#include <asm/ptrace.h>
+struct task_struct;
+
+static inline long syscall_get_nr(struct task_struct *task,
+				  struct pt_regs *regs)
+{
+	return pt_regs_is_syscall(regs) ? regs->u_regs[UREG_G1] : -1L;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+				     struct pt_regs *regs)
+{
+	if (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))
+		return -regs->u_regs[UREG_I0];
+	return 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+					    struct pt_regs *regs)
+{
+	return regs->u_regs[UREG_I0];
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+					    struct pt_regs *regs,
+					    int error, long val)
+{
+	if (error) {
+		regs->tstate |= (TSTATE_XCARRY | TSTATE_ICARRY);
+		regs->u_regs[UREG_I0] = -error;
+	} else {
+		regs->tstate &= ~(TSTATE_XCARRY | TSTATE_ICARRY);
+		regs->u_regs[UREG_I0] = val;
+	}
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+					 struct pt_regs *regs,
+					 unsigned int i, unsigned int n,
+					 unsigned long *args)
+{
+	BUG_ON(i + n > 6);
+#ifdef TIF_32BIT
+	if (test_tsk_thread_flag(task, TIF_32BIT)) {
+		while (n-- > 0)
+			args[n] = (u32) regs->u_regs[UREG_I0 + i + n];
+		return;
+	}
+
+#endif
+	memcpy(args, &regs->u_regs[UREG_I0 + i], n * sizeof(args[0]));
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+					 struct pt_regs *regs,
+					 unsigned int i, unsigned int n,
+					 const unsigned long *args)
+{
+	BUG_ON(i + n > 6);
+	memcpy(&regs->u_regs[UREG_I0 + i], args, n * sizeof(args[0]));
+}
+
+#endif	/* _ASM_SYSCALL_H */
diff --git a/include/asm-sparc/thread_info_64.h b/include/asm-sparc/thread_info_64.h
index c6d2e6c..0ddf16b 100644  
--- a/include/asm-sparc/thread_info_64.h
+++ b/include/asm-sparc/thread_info_64.h
@@ -217,7 +217,7 @@ register struct thread_info *current_thr
  *	 nop
  */
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
-/* flags bit 1 is available */
+#define TIF_NOTIFY_RESUME	1	/* callback before returning to user */
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_PERFCTR		4	/* performance counters active */
@@ -237,6 +237,7 @@ register struct thread_info *current_thr
 #define TIF_POLLING_NRFLAG	14
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_PERFCTR		(1<<TIF_PERFCTR)
@@ -248,8 +249,9 @@ register struct thread_info *current_thr
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_USER_WORK_MASK	((0xff << TI_FLAG_WSAVED_SHIFT) | \
-				 (_TIF_SIGPENDING | \
-				  _TIF_NEED_RESCHED | _TIF_PERFCTR))
+				 _TIF_DO_NOTIFY_RESUME_MASK | \
+				 _TIF_NEED_RESCHED | _TIF_PERFCTR)
+#define _TIF_DO_NOTIFY_RESUME_MASK	(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING)
 
 /*
  * Thread-synchronous status.
diff --git a/include/asm-sparc64/syscall.h b/include/asm-sparc64/syscall.h
new file mode 100644
index ...f084c1f 100644  
--- /dev/null
+++ b/include/asm-sparc64/syscall.h
@@ -0,0 +1 @@
+#include <asm-sparc/syscall.h>

linux-2.6-x86-tracehook.patch:

--- NEW FILE linux-2.6-x86-tracehook.patch ---
 arch/x86/Kconfig              |    1 +
 arch/x86/kernel/ptrace.c      |   34 +------
 arch/x86/kernel/signal_32.c   |   11 ++-
 arch/x86/kernel/signal_64.c   |   49 +++-------
 include/asm-x86/ptrace.h      |    5 +
 include/asm-x86/syscall.h     |  210 +++++++++++++++++++++++++++++++++++++++++
 include/asm-x86/thread_info.h |    4 +-
 7 files changed, 248 insertions(+), 66 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 03980cb..b009ddf 100644  
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -27,6 +27,7 @@ config X86
 	select HAVE_FTRACE
 	select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
 	select HAVE_ARCH_KGDB if !X86_VOYAGER
+	select HAVE_ARCH_TRACEHOOK
 
 config ARCH_DEFCONFIG
 	string
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index e37dccc..19a7d2c 100644  
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -14,6 +14,7 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/regset.h>
+#include <linux/tracehook.h>
 #include <linux/user.h>
 #include <linux/elf.h>
 #include <linux/security.h>
@@ -1375,30 +1376,6 @@ void send_sigtrap(struct task_struct *ts
 	force_sig_info(SIGTRAP, &info, tsk);
 }
 
-static void syscall_trace(struct pt_regs *regs)
-{
-	if (!(current->ptrace & PT_PTRACED))
-		return;
-
-#if 0
-	printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n",
-	       current->comm,
-	       regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0),
-	       current_thread_info()->flags, current->ptrace);
-#endif
-
-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-				? 0x80 : 0));
-	/*
-	 * this isn't the same as continuing with a signal, but it will do
-	 * for normal use.  strace only continues with a signal if the
-	 * stopping signal is not SIGTRAP.  -brl
-	 */
-	if (current->exit_code) {
-		send_sig(current->exit_code, current, 1);
-		current->exit_code = 0;
-	}
-}
 
 #ifdef CONFIG_X86_32
 # define IS_IA32	1
@@ -1432,8 +1409,9 @@ asmregparm long syscall_trace_enter(stru
 	if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
 		ret = -1L;
 
-	if (ret || test_thread_flag(TIF_SYSCALL_TRACE))
-		syscall_trace(regs);
+	if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) &&
+	    tracehook_report_syscall_entry(regs))
+		ret = -1L;
 
 	if (unlikely(current->audit_context)) {
 		if (IS_IA32)
@@ -1459,7 +1437,7 @@ asmregparm void syscall_trace_leave(stru
 		audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
 
 	if (test_thread_flag(TIF_SYSCALL_TRACE))
-		syscall_trace(regs);
+		tracehook_report_syscall_exit(regs, 0);
 
 	/*
 	 * If TIF_SYSCALL_EMU is set, we only get here because of
@@ -1475,6 +1453,6 @@ asmregparm void syscall_trace_leave(stru
 	 * system call instruction.
 	 */
 	if (test_thread_flag(TIF_SINGLESTEP) &&
-	    (current->ptrace & PT_PTRACED))
+	    tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
 		send_sigtrap(current, regs, 0);
 }
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 6fb5bcd..4445d26 100644  
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
+#include <linux/tracehook.h>
 #include <linux/elf.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
@@ -558,8 +559,6 @@ handle_signal(unsigned long sig, siginfo
 	 * handler too.
 	 */
 	regs->flags &= ~X86_EFLAGS_TF;
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
 
 	spin_lock_irq(&current->sighand->siglock);
 	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
@@ -568,6 +567,9 @@ handle_signal(unsigned long sig, siginfo
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
+	tracehook_signal_handler(sig, info, ka, regs,
+				 test_thread_flag(TIF_SINGLESTEP));
+
 	return 0;
 }
 
@@ -661,5 +663,10 @@ do_notify_resume(struct pt_regs *regs, v
 	if (thread_info_flags & _TIF_SIGPENDING)
 		do_signal(regs);
 
+	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+		clear_thread_flag(TIF_NOTIFY_RESUME);
+		tracehook_notify_resume(regs);
+	}
+
 	clear_thread_flag(TIF_IRET);
 }
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 47c3d24..282abdc 100644  
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/personality.h>
@@ -26,6 +27,7 @@
 #include <asm/proto.h>
 #include <asm/ia32_unistd.h>
 #include <asm/mce.h>
+#include <asm/syscall.h>
 #include "sigframe.h"
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -293,35 +295,6 @@ give_sigsegv:
 }
 
 /*
- * Return -1L or the syscall number that @regs is executing.
- */
-static long current_syscall(struct pt_regs *regs)
-{
-	/*
-	 * We always sign-extend a -1 value being set here,
-	 * so this is always either -1L or a syscall number.
-	 */
-	return regs->orig_ax;
-}
-
-/*
- * Return a value that is -EFOO if the system call in @regs->orig_ax
- * returned an error.  This only works for @regs from @current.
- */
-static long current_syscall_ret(struct pt_regs *regs)
-{
-#ifdef CONFIG_IA32_EMULATION
-	if (test_thread_flag(TIF_IA32))
-		/*
-		 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
-		 * and will match correctly in comparisons.
-		 */
-		return (int) regs->ax;
-#endif
-	return regs->ax;
-}
-
-/*
  * OK, we're invoking a handler
  */	
 
@@ -332,9 +305,9 @@ handle_signal(unsigned long sig, siginfo
 	int ret;
 
 	/* Are we from a system call? */
-	if (current_syscall(regs) >= 0) {
+	if (syscall_get_nr(current, regs) >= 0) {
 		/* If so, check system call restarting.. */
-		switch (current_syscall_ret(regs)) {
+		switch (syscall_get_error(current, regs)) {
 		case -ERESTART_RESTARTBLOCK:
 		case -ERESTARTNOHAND:
 			regs->ax = -EINTR;
@@ -391,8 +364,6 @@ handle_signal(unsigned long sig, siginfo
 		 * handler too.
 		 */
 		regs->flags &= ~X86_EFLAGS_TF;
-		if (test_thread_flag(TIF_SINGLESTEP))
-			ptrace_notify(SIGTRAP);
 
 		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -400,6 +371,9 @@ handle_signal(unsigned long sig, siginfo
 			sigaddset(&current->blocked,sig);
 		recalc_sigpending();
 		spin_unlock_irq(&current->sighand->siglock);
+
+		tracehook_signal_handler(sig, info, ka, regs,
+					 test_thread_flag(TIF_SINGLESTEP));
 	}
 
 	return ret;
@@ -456,9 +430,9 @@ static void do_signal(struct pt_regs *re
 	}
 
 	/* Did we come from a system call? */
-	if (current_syscall(regs) >= 0) {
+	if (syscall_get_nr(current, regs) >= 0) {
 		/* Restart the system call - no handlers present */
-		switch (current_syscall_ret(regs)) {
+		switch (syscall_get_error(current, regs)) {
 		case -ERESTARTNOHAND:
 		case -ERESTARTSYS:
 		case -ERESTARTNOINTR:
@@ -496,6 +470,11 @@ void do_notify_resume(struct pt_regs *re
 	/* deal with pending signal delivery */
 	if (thread_info_flags & _TIF_SIGPENDING)
 		do_signal(regs);
+
+	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+		clear_thread_flag(TIF_NOTIFY_RESUME);
+		tracehook_notify_resume(regs);
+	}
 }
 
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h
index 8a71db8..91a77f5 100644  
--- a/include/asm-x86/ptrace.h
+++ b/include/asm-x86/ptrace.h
@@ -213,6 +213,11 @@ static inline unsigned long frame_pointe
 	return regs->bp;
 }
 
+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
+{
+	return regs->sp;
+}
+
 /*
  * These are defined as per linux/ptrace.h, which see.
  */
diff --git a/include/asm-x86/syscall.h b/include/asm-x86/syscall.h
new file mode 100644
index ...6f29389 100644  
--- /dev/null
+++ b/include/asm-x86/syscall.h
@@ -0,0 +1,210 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * See asm-generic/syscall.h for descriptions of what we must do here.
+ */
+
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H	1
+
+#include <linux/sched.h>
+
+static inline long syscall_get_nr(struct task_struct *task,
+				  struct pt_regs *regs)
+{
+	/*
+	 * We always sign-extend a -1 value being set here,
+	 * so this is always either -1L or a syscall number.
+	 */
+	return regs->orig_ax;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+				    struct pt_regs *regs)
+{
+	regs->ax = regs->orig_ax;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+				     struct pt_regs *regs)
+{
+	unsigned long error = regs->ax;
+#ifdef CONFIG_IA32_EMULATION
+	/*
+	 * TS_COMPAT is set for 32-bit syscall entries and then
+	 * remains set until we return to user mode.
+	 */
+	if (task_thread_info(task)->status & TS_COMPAT)
+		/*
+		 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
+		 * and will match correctly in comparisons.
+		 */
+		error = (long) (int) error;
+#endif
+	return error >= -4095L ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+					    struct pt_regs *regs)
+{
+	return regs->ax;
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+					    struct pt_regs *regs,
+					    int error, long val)
+{
+	regs->ax = (long) error ?: val;
+}
+
+#ifdef CONFIG_X86_32
+
+static inline void syscall_get_arguments(struct task_struct *task,
+					 struct pt_regs *regs,
+					 unsigned int i, unsigned int n,
+					 unsigned long *args)
+{
+	BUG_ON(i + n > 6);
+	memcpy(args, &regs->bx + i, n * sizeof(args[0]));
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+					 struct pt_regs *regs,
+					 unsigned int i, unsigned int n,
+					 const unsigned long *args)
+{
+	BUG_ON(i + n > 6);
+	memcpy(&regs->bx + i, args, n * sizeof(args[0]));
+}
+
+#else	 /* CONFIG_X86_64 */
+
+static inline void syscall_get_arguments(struct task_struct *task,
+					 struct pt_regs *regs,
+					 unsigned int i, unsigned int n,
+					 unsigned long *args)
+{
+# ifdef CONFIG_IA32_EMULATION
+	if (task_thread_info(task)->status & TS_COMPAT)
+		switch (i + n) {
+		case 6:
+			if (!n--) break;
+			*args++ = regs->bp;
+		case 5:
+			if (!n--) break;
+			*args++ = regs->di;
+		case 4:
+			if (!n--) break;
+			*args++ = regs->si;
+		case 3:
+			if (!n--) break;
+			*args++ = regs->dx;
+		case 2:
+			if (!n--) break;
+			*args++ = regs->cx;
+		case 1:
+			if (!n--) break;
+			*args++ = regs->bx;
+		case 0:
+			if (!n--) break;
+		default:
+			BUG();
+			break;
+		}
+	else
+# endif
+		switch (i + n) {
+		case 6:
+			if (!n--) break;
+			*args++ = regs->r9;
+		case 5:
+			if (!n--) break;
+			*args++ = regs->r8;
+		case 4:
+			if (!n--) break;
+			*args++ = regs->r10;
+		case 3:
+			if (!n--) break;
+			*args++ = regs->dx;
+		case 2:
+			if (!n--) break;
+			*args++ = regs->si;
+		case 1:
+			if (!n--) break;
+			*args++ = regs->di;
+		case 0:
+			if (!n--) break;
+		default:
+			BUG();
+			break;
+		}
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+					 struct pt_regs *regs,
+					 unsigned int i, unsigned int n,
+					 const unsigned long *args)
+{
+# ifdef CONFIG_IA32_EMULATION
+	if (task_thread_info(task)->status & TS_COMPAT)
+		switch (i + n) {
+		case 6:
+			if (!n--) break;
+			regs->bp = *args++;
+		case 5:
+			if (!n--) break;
+			regs->di = *args++;
+		case 4:
+			if (!n--) break;
+			regs->si = *args++;
+		case 3:
+			if (!n--) break;
+			regs->dx = *args++;
+		case 2:
+			if (!n--) break;
+			regs->cx = *args++;
+		case 1:
+			if (!n--) break;
+			regs->bx = *args++;
+		case 0:
+			if (!n--) break;
+		default:
+			BUG();
+		}
+	else
+# endif
+		switch (i + n) {
+		case 6:
+			if (!n--) break;
+			regs->r9 = *args++;
+		case 5:
+			if (!n--) break;
+			regs->r8 = *args++;
+		case 4:
+			if (!n--) break;
+			regs->r10 = *args++;
+		case 3:
+			if (!n--) break;
+			regs->dx = *args++;
+		case 2:
+			if (!n--) break;
+			regs->si = *args++;
+		case 1:
+			if (!n--) break;
+			regs->di = *args++;
+		case 0:
+			if (!n--) break;
+		default:
+			BUG();
+		}
+}
+
+#endif	/* CONFIG_X86_32 */
+
+#endif	/* _ASM_SYSCALL_H */
diff --git a/include/asm-x86/thread_info.h b/include/asm-x86/thread_info.h
index 3f2de10..29533e3 100644  
--- a/include/asm-x86/thread_info.h
+++ b/include/asm-x86/thread_info.h
@@ -71,6 +71,7 @@ struct thread_info {
  * Warning: layout of LSW is hardcoded in entry.S
  */
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_NOTIFY_RESUME	1	/* callback before returning to user */
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_SINGLESTEP		4	/* reenable singlestep on user return*/
@@ -93,6 +94,7 @@ struct thread_info {
 #define TIF_BTS_TRACE_TS	27      /* record scheduling event timestamps */
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
@@ -133,7 +135,7 @@ struct thread_info {
 
 /* Only used for 64 bit */
 #define _TIF_DO_NOTIFY_MASK						\
-	(_TIF_SIGPENDING|_TIF_MCE_NOTIFY)
+	(_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_NOTIFY_RESUME)
 
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW							\


--- NEW FILE patch-2.6.26-git11.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBIiCl/yGugalF9Dw4RAi/sAKCNbjGv7xjYKaCJG1WxvPzIco3X3QCfZ4gt
WnPP0RjfSYOvXCoEKWwgT5Y=
=2Hyn
-----END PGP SIGNATURE-----


Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/.cvsignore,v
retrieving revision 1.875
retrieving revision 1.876
diff -u -r1.875 -r1.876
--- .cvsignore	23 Jul 2008 19:51:09 -0000	1.875
+++ .cvsignore	24 Jul 2008 08:28:26 -0000	1.876
@@ -4,4 +4,4 @@
 temp-*
 kernel-2.6.26
 linux-2.6.26.tar.bz2
-patch-2.6.26-git10.bz2
+patch-2.6.26-git11.bz2


Index: config-ia64-generic
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/config-ia64-generic,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- config-ia64-generic	23 Jul 2008 19:51:09 -0000	1.14
+++ config-ia64-generic	24 Jul 2008 08:28:26 -0000	1.15
@@ -202,7 +202,4 @@
 CONFIG_KVM=m
 CONFIG_KVM_INTEL=m
 
-CONFIG_UTRACE=n
-CONFIG_UTRACE_PTRACE=n
-
 CONFIG_HP_ILO=m


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.792
retrieving revision 1.793
diff -u -r1.792 -r1.793
--- kernel.spec	24 Jul 2008 08:02:22 -0000	1.792
+++ kernel.spec	24 Jul 2008 08:28:26 -0000	1.793
@@ -45,7 +45,7 @@
 # The rc snapshot level
 %define rcrev 0
 # The git snapshot level
-%define gitrev 10
+%define gitrev 11
 # Set rpm version accordingly
 %define rpmversion 2.6.%{upstream_sublevel}
 %endif
@@ -576,9 +576,11 @@
 
 Patch10: linux-2.6-hotfixes.patch
 
-Patch21: linux-2.6-ptrace-cleanup.patch
-Patch22: linux-2.6-tracehook.patch
-Patch23: linux-2.6-utrace.patch
+Patch20: linux-2.6-tracehook.patch
+Patch21: linux-2.6-utrace.patch
+Patch22: linux-2.6-x86-tracehook.patch
+Patch23: linux-2.6-powerpc-tracehook.patch
+Patch24: linux-2.6-sparc64-tracehook.patch
 
 Patch41: linux-2.6-sysrq-c.patch
 Patch42: linux-2.6-x86-tune-generic.patch
@@ -943,13 +945,14 @@
 else
   # We already have a vanilla dir.
   cd kernel-%{kversion}
-  if [ -d linux-%{kversion}.%{_target_cpu} ]; then
-     # Just in case we ctrl-c'd a prep already
-     rm -rf deleteme.%{_target_cpu}
-     # Move away the stale away, and delete in background.
-     mv linux-%{kversion}.%{_target_cpu} deleteme.%{_target_cpu}
-     rm -rf deleteme.%{_target_cpu} &
-  fi
+fi
+
+if [ -d linux-%{kversion}.%{_target_cpu} ]; then
+  # Just in case we ctrl-c'd a prep already
+  rm -rf deleteme.%{_target_cpu}
+  # Move away the stale away, and delete in background.
+  mv linux-%{kversion}.%{_target_cpu} deleteme.%{_target_cpu}
+  rm -rf deleteme.%{_target_cpu} &
 fi
 
 cp -rl vanilla-%{vanillaversion} linux-%{kversion}.%{_target_cpu}
@@ -1007,9 +1010,11 @@
 ApplyPatch linux-2.6-hotfixes.patch
 
 # Roland's utrace ptrace replacement.
-#ApplyPatch linux-2.6-ptrace-cleanup.patch
-#ApplyPatch linux-2.6-tracehook.patch
-#ApplyPatch linux-2.6-utrace.patch
+ApplyPatch linux-2.6-tracehook.patch
+ApplyPatch linux-2.6-utrace.patch
+ApplyPatch linux-2.6-x86-tracehook.patch
+ApplyPatch linux-2.6-powerpc-tracehook.patch
+ApplyPatch linux-2.6-sparc64-tracehook.patch
 
 # enable sysrq-c on all kernels, not only kexec
 ApplyPatch linux-2.6-sysrq-c.patch
@@ -1777,6 +1782,10 @@
 %kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL}.xen -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.xen.conf %{with_xen} xen
 
 %changelog
+* Thu Jul 24 2008 Roland McGrath <roland at redhat.com>
+- 2.6.26-git11
+- utrace update
+
 * Wed Jul 23 2008 Dave Jones <davej at redhat.com>
 - 2.6.26-git10
 

linux-2.6-tracehook.patch:

Index: linux-2.6-tracehook.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-tracehook.patch,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- linux-2.6-tracehook.patch	14 Jul 2008 19:38:29 -0000	1.4
+++ linux-2.6-tracehook.patch	24 Jul 2008 08:28:26 -0000	1.5
@@ -1,69 +1,38 @@
- arch/Kconfig                      |   18 ++
- arch/ia64/Kconfig                 |    1 +
- arch/ia64/kernel/perfmon.c        |   11 +-
- arch/ia64/kernel/process.c        |   22 +-
- arch/ia64/kernel/ptrace.c         |   43 +--
- arch/ia64/kernel/signal.c         |    8 +
- arch/mips/kernel/irixelf.c        |    2 -
- arch/powerpc/Kconfig              |    1 +
- arch/powerpc/kernel/entry_32.S    |   11 +-
- arch/powerpc/kernel/entry_64.S    |   10 +-
- arch/powerpc/kernel/ptrace.c      |   47 ++--
- arch/powerpc/kernel/signal.c      |   21 ++-
- arch/sparc64/Kconfig              |    1 +
- arch/sparc64/kernel/ptrace.c      |   24 +--
- arch/sparc64/kernel/rtrap.S       |    6 +-
- arch/sparc64/kernel/signal.c      |    5 +
- arch/x86/Kconfig                  |    1 +
- arch/x86/ia32/ia32_aout.c         |    6 -
- arch/x86/kernel/ptrace.c          |   34 +--
- arch/x86/kernel/signal_32.c       |   11 +-
- arch/x86/kernel/signal_64.c       |   49 +---
- 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                         |   12 +-
- fs/proc/array.c                   |    9 +-
- fs/proc/base.c                    |   39 +++-
- include/asm-generic/syscall.h     |  141 +++++++++
- include/asm-ia64/thread_info.h    |    3 -
- include/asm-powerpc/ptrace.h      |    1 +
- include/asm-powerpc/signal.h      |    3 +-
- include/asm-powerpc/syscall.h     |   73 +++++
- include/asm-powerpc/thread_info.h |    5 +-
- include/asm-sparc64/ptrace.h      |    1 +
- include/asm-sparc64/syscall.h     |   70 +++++
- include/asm-sparc64/thread_info.h |    8 +-
- include/asm-x86/ptrace.h          |    5 +
- include/asm-x86/syscall.h         |  210 ++++++++++++++
- include/asm-x86/thread_info_32.h  |    2 +
- include/asm-x86/thread_info_64.h  |    4 +-
- include/linux/ptrace.h            |   72 +++++
- include/linux/sched.h             |   10 +-
- include/linux/tracehook.h         |  575 +++++++++++++++++++++++++++++++++++++
- kernel/exit.c                     |   53 ++---
- kernel/fork.c                     |   74 ++---
- kernel/kthread.c                  |    2 +-
- kernel/ptrace.c                   |    2 +-
- kernel/sched.c                    |   29 ++-
- kernel/signal.c                   |   99 ++++---
- lib/Makefile                      |    2 +
- lib/syscall.c                     |   75 +++++
- mm/nommu.c                        |    4 +-
- security/selinux/hooks.c          |   22 +--
- 55 files changed, 1590 insertions(+), 371 deletions(-)
+ arch/Kconfig                  |   18 ++
+ arch/ia64/kernel/perfmon.c    |    4 +-
+ arch/x86/ia32/ia32_aout.c     |    6 -
+ 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                     |   12 +-
+ fs/proc/array.c               |    9 +-
+ fs/proc/base.c                |   39 +++-
+ include/asm-generic/syscall.h |  141 ++++++++++
+ include/linux/ptrace.h        |   72 +++++
+ include/linux/sched.h         |   10 +-
+ include/linux/tracehook.h     |  575 +++++++++++++++++++++++++++++++++++++++++
+ kernel/exit.c                 |   53 ++---
+ kernel/fork.c                 |   74 ++----
+ kernel/kthread.c              |    2 +-
+ kernel/ptrace.c               |    2 +-
+ kernel/sched.c                |   29 ++-
+ kernel/signal.c               |   99 +++++---
+ lib/Makefile                  |    2 +
+ lib/syscall.c                 |   75 ++++++
+ mm/nommu.c                    |    4 +-
+ security/selinux/hooks.c      |   22 +--
+ 25 files changed, 1084 insertions(+), 188 deletions(-)
 
 diff --git a/arch/Kconfig b/arch/Kconfig
-index 3ea332b..1955fbd 100644  
+index ad89a33..4641edf 100644  
 --- a/arch/Kconfig
 +++ b/arch/Kconfig
-@@ -39,3 +39,21 @@ config HAVE_KRETPROBES
- 
- config HAVE_DMA_ATTRS
+@@ -37,6 +37,24 @@ config HAVE_KPROBES
+ config HAVE_KRETPROBES
  	def_bool n
-+
+ 
 +#
 +# An arch should select this if it provides all these things:
 +#
@@ -81,31 +50,15 @@
 +#
 +config HAVE_ARCH_TRACEHOOK
 +	def_bool n
-diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
-index 16be414..f23a54a 100644  
---- a/arch/ia64/Kconfig
-+++ b/arch/ia64/Kconfig
-@@ -19,6 +19,7 @@ config IA64
- 	select HAVE_OPROFILE
- 	select HAVE_KPROBES
- 	select HAVE_KRETPROBES
-+	select HAVE_ARCH_TRACEHOOK
- 	select HAVE_DMA_ATTRS
- 	select HAVE_KVM
- 	default y
++
+ config HAVE_DMA_ATTRS
+ 	def_bool n
+ 
 diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
-index 7714a97..189d525 100644  
+index 19d4493..fc8f350 100644  
 --- a/arch/ia64/kernel/perfmon.c
 +++ b/arch/ia64/kernel/perfmon.c
-@@ -40,6 +40,7 @@
- #include <linux/capability.h>
- #include <linux/rcupdate.h>
- #include <linux/completion.h>
-+#include <linux/tracehook.h>
- 
- #include <asm/errno.h>
- #include <asm/intrinsics.h>
-@@ -2626,7 +2627,7 @@ pfm_task_incompatible(pfm_context_t *ctx
+@@ -2626,7 +2626,7 @@ pfm_task_incompatible(pfm_context_t *ctx
  	/*
  	 * make sure the task is off any CPU
  	 */
@@ -114,16 +67,7 @@
  
  	/* more to come... */
  
-@@ -3684,7 +3685,7 @@ pfm_restart(pfm_context_t *ctx, void *ar
- 
- 		PFM_SET_WORK_PENDING(task, 1);
- 
--		tsk_set_notify_resume(task);
-+		set_notify_resume(task);
- 
- 		/*
- 		 * XXX: send reschedule if task runs on another CPU
-@@ -4774,7 +4775,7 @@ recheck:
+@@ -4774,7 +4774,7 @@ recheck:
  
  		UNPROTECT_CTX(ctx, flags);
  
@@ -132,541 +76,6 @@
  
  		PROTECT_CTX(ctx, flags);
  
-@@ -5044,8 +5045,6 @@ pfm_handle_work(void)
- 
- 	PFM_SET_WORK_PENDING(current, 0);
- 
--	tsk_clear_notify_resume(current);
--
- 	regs = task_pt_regs(current);
- 
- 	/*
-@@ -5414,7 +5413,7 @@ pfm_overflow_handler(struct task_struct 
- 			 * when coming from ctxsw, current still points to the
- 			 * previous task, therefore we must work with task and not current.
- 			 */
--			tsk_set_notify_resume(task);
-+			set_notify_resume(task);
- 		}
- 		/*
- 		 * defer until state is changed (shorten spin window). the context is locked
-diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
-index a3a34b4..5164aab 100644  
---- a/arch/ia64/kernel/process.c
-+++ b/arch/ia64/kernel/process.c
-@@ -28,6 +28,7 @@
- #include <linux/delay.h>
- #include <linux/kdebug.h>
- #include <linux/utsname.h>
-+#include <linux/tracehook.h>
- 
- #include <asm/cpu.h>
- #include <asm/delay.h>
-@@ -156,21 +157,6 @@ show_regs (struct pt_regs *regs)
- 		show_stack(NULL, NULL);
- }
- 
--void tsk_clear_notify_resume(struct task_struct *tsk)
--{
--#ifdef CONFIG_PERFMON
--	if (tsk->thread.pfm_needs_checking)
--		return;
--#endif
--	if (test_ti_thread_flag(task_thread_info(tsk), TIF_RESTORE_RSE))
--		return;
--	clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME);
--}
--
--/*
-- * do_notify_resume_user():
-- *	Called from notify_resume_user at entry.S, with interrupts disabled.
-- */
- void
- do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
- {
-@@ -199,6 +185,11 @@ do_notify_resume_user(sigset_t *unused, 
- 		ia64_do_signal(scr, in_syscall);
- 	}
- 
-+	if (test_thread_flag(TIF_NOTIFY_RESUME)) {
-+		clear_thread_flag(TIF_NOTIFY_RESUME);
-+		tracehook_notify_resume(&scr->pt);
-+	}
-+
- 	/* copy user rbs to kernel rbs */
- 	if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) {
- 		local_irq_enable();	/* force interrupt enable */
-diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
-index 2a9943b..3ba40a1 100644  
---- a/arch/ia64/kernel/ptrace.c
-+++ b/arch/ia64/kernel/ptrace.c
-@@ -22,6 +22,7 @@
- #include <linux/signal.h>
- #include <linux/regset.h>
- #include <linux/elf.h>
-+#include <linux/tracehook.h>
- 
- #include <asm/pgtable.h>
- #include <asm/processor.h>
-@@ -603,7 +604,7 @@ void ia64_ptrace_stop(void)
- {
- 	if (test_and_set_tsk_thread_flag(current, TIF_RESTORE_RSE))
- 		return;
--	tsk_set_notify_resume(current);
-+	set_notify_resume(current);
- 	unw_init_running(do_sync_rbs, ia64_sync_user_rbs);
- }
- 
-@@ -613,7 +614,6 @@ void ia64_ptrace_stop(void)
- void ia64_sync_krbs(void)
- {
- 	clear_tsk_thread_flag(current, TIF_RESTORE_RSE);
--	tsk_clear_notify_resume(current);
- 
- 	unw_init_running(do_sync_rbs, ia64_sync_kernel_rbs);
- }
-@@ -644,7 +644,7 @@ ptrace_attach_sync_user_rbs (struct task
- 		spin_lock_irq(&child->sighand->siglock);
- 		if (child->state == TASK_STOPPED &&
- 		    !test_and_set_tsk_thread_flag(child, TIF_RESTORE_RSE)) {
--			tsk_set_notify_resume(child);
-+			set_notify_resume(child);
- 
- 			child->state = TASK_TRACED;
- 			stopped = 1;
-@@ -1232,27 +1232,6 @@ arch_ptrace (struct task_struct *child, 
- }
- 
- 
--static void
--syscall_trace (void)
--{
--	/*
--	 * The 0x80 provides a way for the tracing parent to
--	 * distinguish between a syscall stop and SIGTRAP delivery.
--	 */
--	ptrace_notify(SIGTRAP
--		      | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
--
--	/*
--	 * This isn't the same as continuing with a signal, but it
--	 * will do for normal use.  strace only continues with a
--	 * signal if the stopping signal is not SIGTRAP.  -brl
--	 */
--	if (current->exit_code) {
--		send_sig(current->exit_code, current, 1);
--		current->exit_code = 0;
--	}
--}
--
- /* "asmlinkage" so the input arguments are preserved... */
- 
- asmlinkage void
-@@ -1260,9 +1239,8 @@ syscall_trace_enter (long arg0, long arg
- 		     long arg4, long arg5, long arg6, long arg7,
- 		     struct pt_regs regs)
- {
--	if (test_thread_flag(TIF_SYSCALL_TRACE) 
--	    && (current->ptrace & PT_PTRACED))
--		syscall_trace();
-+	if (test_thread_flag(TIF_SYSCALL_TRACE))
-+		tracehook_report_syscall_entry(&regs);
- 
- 	/* copy user rbs to kernel rbs */
- 	if (test_thread_flag(TIF_RESTORE_RSE))
-@@ -1292,6 +1270,8 @@ syscall_trace_leave (long arg0, long arg
- 		     long arg4, long arg5, long arg6, long arg7,
- 		     struct pt_regs regs)
- {
-+	int step;
-+
- 	if (unlikely(current->audit_context)) {
- 		int success = AUDITSC_RESULT(regs.r10);
- 		long result = regs.r8;
-@@ -1301,10 +1281,9 @@ syscall_trace_leave (long arg0, long arg
- 		audit_syscall_exit(success, result);
- 	}
- 
--	if ((test_thread_flag(TIF_SYSCALL_TRACE)
--	    || test_thread_flag(TIF_SINGLESTEP))
--	    && (current->ptrace & PT_PTRACED))
--		syscall_trace();
-+	step = test_thread_flag(TIF_SINGLESTEP);
-+	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
-+		tracehook_report_syscall_exit(&regs, step);
- 
- 	/* copy user rbs to kernel rbs */
- 	if (test_thread_flag(TIF_RESTORE_RSE))
-@@ -1940,7 +1919,7 @@ gpregs_writeback(struct task_struct *tar
- {
- 	if (test_and_set_tsk_thread_flag(target, TIF_RESTORE_RSE))
- 		return 0;
--	tsk_set_notify_resume(target);
-+	set_notify_resume(target);
- 	return do_regset_call(do_gpregs_writeback, target, regset, 0, 0,
- 		NULL, NULL);
- }
-diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
-index 19c5a78..e12500a 100644  
---- a/arch/ia64/kernel/signal.c
-+++ b/arch/ia64/kernel/signal.c
-@@ -11,6 +11,7 @@
- #include <linux/kernel.h>
- #include <linux/mm.h>
- #include <linux/ptrace.h>
-+#include <linux/tracehook.h>
- #include <linux/sched.h>
- #include <linux/signal.h>
- #include <linux/smp.h>
-@@ -439,6 +440,13 @@ handle_signal (unsigned long sig, struct
- 		sigaddset(&current->blocked, sig);
- 	recalc_sigpending();
- 	spin_unlock_irq(&current->sighand->siglock);
-+
-+	/*
-+	 * Let tracing know that we've done the handler setup.
-+	 */
-+	tracehook_signal_handler(sig, info, ka, &scr->pt,
-+				 test_thread_flag(TIF_SINGLESTEP));
-+
- 	return 1;
- }
- 
-diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
-index 469c723..a48edbe 100644  
---- a/arch/mips/kernel/irixelf.c
-+++ b/arch/mips/kernel/irixelf.c
-@@ -808,8 +808,6 @@ static int load_irix_binary(struct linux
- #endif
- 
- 	start_thread(regs, elf_entry, bprm->p);
--	if (current->ptrace & PT_PTRACED)
--		send_sig(SIGTRAP, current, 0);
- 	return 0;
- out:
- 	return retval;
-diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
-index 3934e26..52486c7 100644  
---- a/arch/powerpc/Kconfig
-+++ b/arch/powerpc/Kconfig
-@@ -109,6 +109,7 @@ config PPC
- 	select HAVE_OPROFILE
- 	select HAVE_KPROBES
- 	select HAVE_KRETPROBES
-+	select HAVE_ARCH_TRACEHOOK
- 	select HAVE_LMB
- 
- config EARLY_PRINTK
-diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
-index 3a05e9f..eb40c67 100644  
---- a/arch/powerpc/kernel/entry_32.S
-+++ b/arch/powerpc/kernel/entry_32.S
-@@ -299,7 +299,12 @@ syscall_dotrace:
- 	stw	r0,_TRAP(r1)
- 	addi	r3,r1,STACK_FRAME_OVERHEAD
- 	bl	do_syscall_trace_enter
--	lwz	r0,GPR0(r1)	/* Restore original registers */
-+	/*
-+	 * Restore argument registers possibly just changed.
-+	 * We use the return value of do_syscall_trace_enter
-+	 * for call number to look up in the table (r0).
-+	 */
-+	mr	r0,r3
- 	lwz	r3,GPR3(r1)
- 	lwz	r4,GPR4(r1)
- 	lwz	r5,GPR5(r1)
-@@ -938,8 +943,8 @@ do_user_signal:			/* r10 contains MSR_KE
- 	SAVE_NVGPRS(r1)
- 	rlwinm	r3,r3,0,0,30
- 	stw	r3,_TRAP(r1)
--2:	li	r3,0
--	addi	r4,r1,STACK_FRAME_OVERHEAD
-+2:	addi	r3,r1,STACK_FRAME_OVERHEAD
-+	mr	r4,r9
- 	bl	do_signal
- 	REST_NVGPRS(r1)
- 	b	recheck
-diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
-index c0db5b7..2a13029 100644  
---- a/arch/powerpc/kernel/entry_64.S
-+++ b/arch/powerpc/kernel/entry_64.S
-@@ -213,7 +213,12 @@ syscall_dotrace:
- 	bl	.save_nvgprs
- 	addi	r3,r1,STACK_FRAME_OVERHEAD
- 	bl	.do_syscall_trace_enter
--	ld	r0,GPR0(r1)	/* Restore original registers */
-+	/*
-+	 * Restore argument registers possibly just changed.
-+	 * We use the return value of do_syscall_trace_enter
-+	 * for the call number to look up in the table (r0).
-+	 */
-+	mr	r0,r3
- 	ld	r3,GPR3(r1)
- 	ld	r4,GPR4(r1)
- 	ld	r5,GPR5(r1)
-@@ -632,8 +637,7 @@ user_work:
- 	b	.ret_from_except_lite
- 
- 1:	bl	.save_nvgprs
--	li	r3,0
--	addi	r4,r1,STACK_FRAME_OVERHEAD
-+	addi	r3,r1,STACK_FRAME_OVERHEAD
- 	bl	.do_signal
- 	b	.ret_from_except
- 
-diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
-index 91ee077..b9bf411 100644  
---- a/arch/powerpc/kernel/ptrace.c
-+++ b/arch/powerpc/kernel/ptrace.c
-@@ -22,6 +22,7 @@
- #include <linux/errno.h>
- #include <linux/ptrace.h>
- #include <linux/regset.h>
-+#include <linux/tracehook.h>
- #include <linux/elf.h>
- #include <linux/user.h>
- #include <linux/security.h>
-@@ -866,31 +867,24 @@ long arch_ptrace(struct task_struct *chi
- 	return ret;
- }
- 
--static void do_syscall_trace(void)
-+/*
-+ * We must return the syscall number to actually look up in the table.
-+ * This can be -1L to skip running any syscall at all.
-+ */
-+long do_syscall_trace_enter(struct pt_regs *regs)
- {
--	/* the 0x80 provides a way for the tracing parent to distinguish
--	   between a syscall stop and SIGTRAP delivery */
--	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
--				 ? 0x80 : 0));
--
--	/*
--	 * this isn't the same as continuing with a signal, but it will do
--	 * for normal use.  strace only continues with a signal if the
--	 * stopping signal is not SIGTRAP.  -brl
--	 */
--	if (current->exit_code) {
--		send_sig(current->exit_code, current, 1);
--		current->exit_code = 0;
--	}
--}
-+	long ret = 0;
- 
--void do_syscall_trace_enter(struct pt_regs *regs)
--{
- 	secure_computing(regs->gpr[0]);
- 
--	if (test_thread_flag(TIF_SYSCALL_TRACE)
--	    && (current->ptrace & PT_PTRACED))
--		do_syscall_trace();
-+	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
-+	    tracehook_report_syscall_entry(regs))
-+		/*
-+		 * Tracing decided this syscall should not happen.
-+		 * We'll return a bogus call number to get an ENOSYS
-+		 * error, but leave the original number in regs->gpr[0].
-+		 */
-+		ret = -1L;
- 
- 	if (unlikely(current->audit_context)) {
- #ifdef CONFIG_PPC64
-@@ -908,16 +902,19 @@ void do_syscall_trace_enter(struct pt_re
- 					    regs->gpr[5] & 0xffffffff,
- 					    regs->gpr[6] & 0xffffffff);
- 	}
-+
-+	return ret ?: regs->gpr[0];
- }
- 
- void do_syscall_trace_leave(struct pt_regs *regs)
- {
-+	int step;
-+
- 	if (unlikely(current->audit_context))
- 		audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
- 				   regs->result);
- 
--	if ((test_thread_flag(TIF_SYSCALL_TRACE)
--	     || test_thread_flag(TIF_SINGLESTEP))
--	    && (current->ptrace & PT_PTRACED))
--		do_syscall_trace();
-+	step = test_thread_flag(TIF_SINGLESTEP);
-+	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
-+		tracehook_report_syscall_exit(regs, step);
- }
-diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
-index ad55488..e032336 100644  
---- a/arch/powerpc/kernel/signal.c
-+++ b/arch/powerpc/kernel/signal.c
-@@ -9,7 +9,7 @@
-  * this archive for more details.
-  */
- 
--#include <linux/ptrace.h>
-+#include <linux/tracehook.h>
- #include <linux/signal.h>
- #include <asm/uaccess.h>
- #include <asm/unistd.h>
-@@ -112,7 +112,7 @@ static void check_syscall_restart(struct
- 	}
- }
- 
--int do_signal(sigset_t *oldset, struct pt_regs *regs)
-+static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
- {
- 	siginfo_t info;
- 	int signr;
-@@ -173,11 +173,28 @@ int do_signal(sigset_t *oldset, struct p
- 		 * its frame, and we can clear the TLF_RESTORE_SIGMASK flag.
- 		 */
- 		current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK;
-+
-+		/*
-+		 * Let tracing know that we've done the handler setup.
-+		 */
-+		tracehook_signal_handler(signr, &info, &ka, regs,
-+					 test_thread_flag(TIF_SINGLESTEP));
- 	}
- 
- 	return ret;
- }
- 
-+void do_signal(struct pt_regs *regs, unsigned long thread_info_flags)
-+{
-+	if (thread_info_flags & _TIF_SIGPENDING)
-+		do_signal_pending(NULL, regs);
-+
-+	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
-+		clear_thread_flag(TIF_NOTIFY_RESUME);
-+		tracehook_notify_resume(regs);
-+	}
-+}
-+
- long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
- 		unsigned long r5, unsigned long r6, unsigned long r7,
- 		unsigned long r8, struct pt_regs *regs)
-diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
-index eb36f3b..94504d4 100644  
---- a/arch/sparc64/Kconfig
-+++ b/arch/sparc64/Kconfig
-@@ -11,6 +11,7 @@ config SPARC
- config SPARC64
- 	bool
- 	default y
-+	select HAVE_ARCH_TRACEHOOK
- 	select HAVE_IDE
- 	select HAVE_LMB
- 	select HAVE_ARCH_KGDB
-diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
-index f6c9fc9..2e3f998 100644  
---- a/arch/sparc64/kernel/ptrace.c
-+++ b/arch/sparc64/kernel/ptrace.c
-@@ -23,6 +23,7 @@
- #include <linux/audit.h>
- #include <linux/signal.h>
- #include <linux/regset.h>
-+#include <linux/tracehook.h>
- #include <linux/compat.h>
- #include <linux/elf.h>
- 
-@@ -1064,26 +1065,13 @@ asmlinkage void syscall_trace(struct pt_
- 		audit_syscall_exit(result, regs->u_regs[UREG_I0]);
- 	}
- 
--	if (!(current->ptrace & PT_PTRACED))
--		goto out;
--
--	if (!test_thread_flag(TIF_SYSCALL_TRACE))
--		goto out;
--
--	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
--				 ? 0x80 : 0));
--
--	/*
--	 * this isn't the same as continuing with a signal, but it will do
--	 * for normal use.  strace only continues with a signal if the
--	 * stopping signal is not SIGTRAP.  -brl
--	 */
--	if (current->exit_code) {
--		send_sig(current->exit_code, current, 1);
--		current->exit_code = 0;
-+	if (test_thread_flag(TIF_SYSCALL_TRACE)) {
-+		if (syscall_exit_p)
-+			tracehook_report_syscall_exit(regs, 0);
-+		else
-+			tracehook_report_syscall_entry(regs);
- 	}
- 
--out:
- 	if (unlikely(current->audit_context) && !syscall_exit_p)
- 		audit_syscall_entry((test_thread_flag(TIF_32BIT) ?
- 				     AUDIT_ARCH_SPARC :
-diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
-index c6fc695..97a993c 100644  
---- a/arch/sparc64/kernel/rtrap.S
-+++ b/arch/sparc64/kernel/rtrap.S
-@@ -46,7 +46,7 @@ __handle_user_windows:
- 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
- 		ldx			[%g6 + TI_FLAGS], %l0
- 
--1:		andcc			%l0, _TIF_SIGPENDING, %g0
-+1:		andcc			%l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
- 		be,pt			%xcc, __handle_user_windows_continue
- 		 nop
- 		mov			%l5, %o1
-@@ -86,7 +86,7 @@ __handle_perfctrs:
- 		 wrpr			%g0, RTRAP_PSTATE, %pstate
- 		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate
- 		ldx			[%g6 + TI_FLAGS], %l0
--1:		andcc			%l0, _TIF_SIGPENDING, %g0
-+1:		andcc			%l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
- 
- 		be,pt			%xcc, __handle_perfctrs_continue
- 		 sethi			%hi(TSTATE_PEF), %o0
-@@ -195,7 +195,7 @@ __handle_preemption_continue:
- 		 andcc			%l1, %o0, %g0
- 		andcc			%l0, _TIF_NEED_RESCHED, %g0
- 		bne,pn			%xcc, __handle_preemption
--		 andcc			%l0, _TIF_SIGPENDING, %g0
-+		 andcc			%l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0
- 		bne,pn			%xcc, __handle_signal
- __handle_signal_continue:
- 		 ldub			[%g6 + TI_WSAVED], %o2
-diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
-index 9667e96..9424fda 100644  
---- a/arch/sparc64/kernel/signal.c
-+++ b/arch/sparc64/kernel/signal.c
-@@ -17,6 +17,7 @@
- #include <linux/errno.h>
- #include <linux/wait.h>
- #include <linux/ptrace.h>
-+#include <linux/tracehook.h>
- #include <linux/unistd.h>
- #include <linux/mm.h>
- #include <linux/tty.h>
-@@ -605,4 +606,8 @@ void do_notify_resume(struct pt_regs *re
- {
- 	if (thread_info_flags & _TIF_SIGPENDING)
- 		do_signal(regs, orig_i0);
-+	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
-+		clear_thread_flag(TIF_NOTIFY_RESUME);
-+		tracehook_notify_resume(regs);
-+	}
- }
-diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index bf07b6f..1c42efb 100644  
---- a/arch/x86/Kconfig
-+++ b/arch/x86/Kconfig
-@@ -25,6 +25,7 @@ config X86
- 	select HAVE_KRETPROBES
- 	select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
- 	select HAVE_ARCH_KGDB if !X86_VOYAGER
-+	select HAVE_ARCH_TRACEHOOK
- 
- config ARCH_DEFCONFIG
- 	string
 diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
 index 58cccb6..a0e1dbe 100644  
 --- a/arch/x86/ia32/ia32_aout.c
@@ -684,232 +93,6 @@
  	return 0;
  }
  
-diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
-index 652f550..d537484 100644  
---- a/arch/x86/kernel/ptrace.c
-+++ b/arch/x86/kernel/ptrace.c
-@@ -14,6 +14,7 @@
- #include <linux/errno.h>
- #include <linux/ptrace.h>
- #include <linux/regset.h>
-+#include <linux/tracehook.h>
- #include <linux/user.h>
- #include <linux/elf.h>
- #include <linux/security.h>
-@@ -1375,30 +1376,6 @@ void send_sigtrap(struct task_struct *ts
- 	force_sig_info(SIGTRAP, &info, tsk);
- }
- 
--static void syscall_trace(struct pt_regs *regs)
--{
--	if (!(current->ptrace & PT_PTRACED))
--		return;
--
--#if 0
--	printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n",
--	       current->comm,
--	       regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0),
--	       current_thread_info()->flags, current->ptrace);
--#endif
--
--	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
--				? 0x80 : 0));
--	/*
--	 * this isn't the same as continuing with a signal, but it will do
--	 * for normal use.  strace only continues with a signal if the
--	 * stopping signal is not SIGTRAP.  -brl
--	 */
--	if (current->exit_code) {
--		send_sig(current->exit_code, current, 1);
--		current->exit_code = 0;
--	}
--}
- 
- #ifdef CONFIG_X86_32
- # define IS_IA32	1
-@@ -1432,8 +1409,9 @@ asmregparm long syscall_trace_enter(stru
- 	if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
- 		ret = -1L;
- 
--	if (ret || test_thread_flag(TIF_SYSCALL_TRACE))
--		syscall_trace(regs);
-+	if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) &&
-+	    tracehook_report_syscall_entry(regs))
-+		ret = -1L;
- 
- 	if (unlikely(current->audit_context)) {
- 		if (IS_IA32)
-@@ -1459,7 +1437,7 @@ asmregparm void syscall_trace_leave(stru
- 		audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
- 
- 	if (test_thread_flag(TIF_SYSCALL_TRACE))
--		syscall_trace(regs);
-+		tracehook_report_syscall_exit(regs, 0);
- 
- 	/*
- 	 * If TIF_SYSCALL_EMU is set, we only get here because of
-@@ -1475,6 +1453,6 @@ asmregparm void syscall_trace_leave(stru
- 	 * system call instruction.
- 	 */
- 	if (test_thread_flag(TIF_SINGLESTEP) &&
--	    (current->ptrace & PT_PTRACED))
-+	    tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
- 		send_sigtrap(current, regs, 0);
- }
-diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
-index 295b5f5..c17c0cb 100644  
---- a/arch/x86/kernel/signal_32.c
-+++ b/arch/x86/kernel/signal_32.c
-@@ -17,6 +17,7 @@
- #include <linux/errno.h>
- #include <linux/sched.h>
- #include <linux/wait.h>
-+#include <linux/tracehook.h>
- #include <linux/elf.h>
- #include <linux/smp.h>
- #include <linux/mm.h>
-@@ -558,8 +559,6 @@ handle_signal(unsigned long sig, siginfo
- 	 * handler too.
- 	 */
- 	regs->flags &= ~X86_EFLAGS_TF;
--	if (test_thread_flag(TIF_SINGLESTEP))
--		ptrace_notify(SIGTRAP);
- 
- 	spin_lock_irq(&current->sighand->siglock);
- 	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-@@ -568,6 +567,9 @@ handle_signal(unsigned long sig, siginfo
- 	recalc_sigpending();
- 	spin_unlock_irq(&current->sighand->siglock);
- 
-+	tracehook_signal_handler(sig, info, ka, regs,
-+				 test_thread_flag(TIF_SINGLESTEP));
-+
- 	return 0;
- }
- 
-@@ -661,6 +663,11 @@ do_notify_resume(struct pt_regs *regs, v
- 	if (thread_info_flags & _TIF_SIGPENDING)
- 		do_signal(regs);
- 
-+	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
-+		clear_thread_flag(TIF_NOTIFY_RESUME);
-+		tracehook_notify_resume(regs);
-+	}
-+
- 	if (thread_info_flags & _TIF_HRTICK_RESCHED)
- 		hrtick_resched();
- 
-diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
-index bf87684..f65ece6 100644  
---- a/arch/x86/kernel/signal_64.c
-+++ b/arch/x86/kernel/signal_64.c
-@@ -15,6 +15,7 @@
- #include <linux/errno.h>
- #include <linux/wait.h>
- #include <linux/ptrace.h>
-+#include <linux/tracehook.h>
- #include <linux/unistd.h>
- #include <linux/stddef.h>
- #include <linux/personality.h>
-@@ -26,6 +27,7 @@
- #include <asm/proto.h>
- #include <asm/ia32_unistd.h>
- #include <asm/mce.h>
-+#include <asm/syscall.h>
- #include "sigframe.h"
- 
- #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-@@ -293,35 +295,6 @@ give_sigsegv:
- }
- 
- /*
-- * Return -1L or the syscall number that @regs is executing.
-- */
--static long current_syscall(struct pt_regs *regs)
--{
--	/*
--	 * We always sign-extend a -1 value being set here,
--	 * so this is always either -1L or a syscall number.
--	 */
--	return regs->orig_ax;
--}
--
--/*
-- * Return a value that is -EFOO if the system call in @regs->orig_ax
-- * returned an error.  This only works for @regs from @current.
-- */
--static long current_syscall_ret(struct pt_regs *regs)
--{
--#ifdef CONFIG_IA32_EMULATION
--	if (test_thread_flag(TIF_IA32))
--		/*
--		 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
--		 * and will match correctly in comparisons.
--		 */
--		return (int) regs->ax;
--#endif
--	return regs->ax;
--}
--
--/*
-  * OK, we're invoking a handler
-  */	
- 
-@@ -332,9 +305,9 @@ handle_signal(unsigned long sig, siginfo
- 	int ret;
- 
- 	/* Are we from a system call? */
--	if (current_syscall(regs) >= 0) {
-+	if (syscall_get_nr(current, regs) >= 0) {
- 		/* If so, check system call restarting.. */
--		switch (current_syscall_ret(regs)) {
-+		switch (syscall_get_error(current, regs)) {
- 		case -ERESTART_RESTARTBLOCK:
- 		case -ERESTARTNOHAND:
- 			regs->ax = -EINTR;
-@@ -391,8 +364,6 @@ handle_signal(unsigned long sig, siginfo
- 		 * handler too.
- 		 */
- 		regs->flags &= ~X86_EFLAGS_TF;
--		if (test_thread_flag(TIF_SINGLESTEP))
--			ptrace_notify(SIGTRAP);
- 
- 		spin_lock_irq(&current->sighand->siglock);
- 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-@@ -400,6 +371,9 @@ handle_signal(unsigned long sig, siginfo
- 			sigaddset(&current->blocked,sig);
- 		recalc_sigpending();
- 		spin_unlock_irq(&current->sighand->siglock);
-+
-+		tracehook_signal_handler(sig, info, ka, regs,
-+					 test_thread_flag(TIF_SINGLESTEP));
- 	}
- 
- 	return ret;
-@@ -456,9 +430,9 @@ static void do_signal(struct pt_regs *re
- 	}
- 
- 	/* Did we come from a system call? */
--	if (current_syscall(regs) >= 0) {
-+	if (syscall_get_nr(current, regs) >= 0) {
- 		/* Restart the system call - no handlers present */
--		switch (current_syscall_ret(regs)) {
-+		switch (syscall_get_error(current, regs)) {
- 		case -ERESTARTNOHAND:
- 		case -ERESTARTSYS:
- 		case -ERESTARTNOINTR:
-@@ -497,6 +471,11 @@ void do_notify_resume(struct pt_regs *re
- 	if (thread_info_flags & _TIF_SIGPENDING)
- 		do_signal(regs);
- 
-+	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
-+		clear_thread_flag(TIF_NOTIFY_RESUME);
-+		tracehook_notify_resume(regs);
-+	}
-+
- 	if (thread_info_flags & _TIF_HRTICK_RESCHED)
- 		hrtick_resched();
- }
 diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
 index ba4cddb..204cfd1 100644  
 --- a/fs/binfmt_aout.c
@@ -928,10 +111,10 @@
  }
  
 diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
-index d48ff5f..66a2bdc 100644  
+index 639d2d8..fcfe706 100644  
 --- a/fs/binfmt_elf.c
 +++ b/fs/binfmt_elf.c
-@@ -974,12 +974,6 @@ static int load_elf_binary(struct linux_
+@@ -975,12 +975,6 @@ static int load_elf_binary(struct linux_
  #endif
  
  	start_thread(regs, elf_entry, bprm->p);
@@ -1061,7 +244,7 @@
  		"State:\t%s\n"
  		"Tgid:\t%d\n"
 diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 3b45537..eb59321 100644  
+index 58c3e6a..6c950c7 100644  
 --- a/fs/proc/base.c
 +++ b/fs/proc/base.c
 @@ -69,6 +69,7 @@
@@ -1078,20 +261,20 @@
  	 */
 -	if (task->parent == current && (task->ptrace & PT_PTRACED) &&
 -	    task_is_stopped_or_traced(task) &&
--	    ptrace_may_attach(task))
+-	    ptrace_may_access(task, PTRACE_MODE_ATTACH))
 -		return 0;
 +	if (task_is_stopped_or_traced(task)) {
 +		int match;
 +		rcu_read_lock();
 +		match = (tracehook_tracer_task(task) == current);
 +		rcu_read_unlock();
-+		if (match && ptrace_may_attach(task))
++		if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH))
 +			return 0;
 +	}
  
  	/*
  	 * Noone else is allowed.
-@@ -503,6 +508,26 @@ static int proc_pid_limits(struct task_s
+@@ -504,6 +509,26 @@ static int proc_pid_limits(struct task_s
  	return count;
  }
  
@@ -1118,7 +301,7 @@
  /************************************************************************/
  /*                       Here the fs part begins                        */
  /************************************************************************/
-@@ -2419,6 +2444,9 @@ static const struct pid_entry tgid_base_
+@@ -2420,6 +2445,9 @@ static const struct pid_entry tgid_base_
  #ifdef CONFIG_SCHED_DEBUG
  	REG("sched",      S_IRUGO|S_IWUSR, pid_sched),
  #endif
@@ -1128,7 +311,7 @@
  	INF("cmdline",    S_IRUGO, pid_cmdline),
  	ONE("stat",       S_IRUGO, tgid_stat),
  	ONE("statm",      S_IRUGO, pid_statm),
-@@ -2751,6 +2779,9 @@ static const struct pid_entry tid_base_s
+@@ -2752,6 +2780,9 @@ static const struct pid_entry tid_base_s
  #ifdef CONFIG_SCHED_DEBUG
  	REG("sched",     S_IRUGO|S_IWUSR, pid_sched),
  #endif
@@ -1140,7 +323,7 @@
  	ONE("statm",     S_IRUGO, pid_statm),
 diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h
 new file mode 100644
-index ...fd57a55 100644  
+index ...abcf34c 100644  
 --- /dev/null
 +++ b/include/asm-generic/syscall.h
 @@ -0,0 +1,141 @@
@@ -1264,7 +447,7 @@
 +			   unsigned int i, unsigned int n, unsigned long *args);
 +
 +/**
-+ * syscall_set_argument - change system call parameter value
++ * syscall_set_arguments - change system call parameter value
 + * @task:	task of interest, must be in system call entry tracing
 + * @regs:	task_pt_regs() of @task
 + * @i:		argument index [0,5]
@@ -1285,560 +468,11 @@
 +			   const unsigned long *args);
 +
 +#endif	/* _ASM_SYSCALL_H */
-diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
-index 2422ac6..05158b8 100644  
---- a/include/asm-ia64/thread_info.h
-+++ b/include/asm-ia64/thread_info.h
-@@ -85,9 +85,6 @@ struct thread_info {
- #define alloc_task_struct()	((struct task_struct *)__get_free_pages(GFP_KERNEL | __GFP_COMP, KERNEL_STACK_SIZE_ORDER))
- #define free_task_struct(tsk)	free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER)
- 
--#define tsk_set_notify_resume(tsk) \
--	set_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME)
--extern void tsk_clear_notify_resume(struct task_struct *tsk);
- #endif /* !__ASSEMBLY */
- 
- /*
-diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
-index 6a3892d..33ec703 100644  
---- a/include/asm-powerpc/ptrace.h
-+++ b/include/asm-powerpc/ptrace.h
-@@ -84,6 +84,7 @@ struct pt_regs {
- #ifndef __ASSEMBLY__
- 
- #define instruction_pointer(regs) ((regs)->nip)
-+#define user_stack_pointer(regs) ((regs)->gpr[1])
- #define regs_return_value(regs) ((regs)->gpr[3])
- 
- #ifdef CONFIG_SMP
-diff --git a/include/asm-powerpc/signal.h b/include/asm-powerpc/signal.h
-index a8c7bab..a7360cd 100644  
---- a/include/asm-powerpc/signal.h
-+++ b/include/asm-powerpc/signal.h
-@@ -122,8 +122,7 @@ typedef struct sigaltstack {
- 
- #ifdef __KERNEL__
- struct pt_regs;
--extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
--extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
-+extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags);
- #define ptrace_signal_deliver(regs, cookie) do { } while (0)
- #endif /* __KERNEL__ */
- 
-diff --git a/include/asm-powerpc/syscall.h b/include/asm-powerpc/syscall.h
-new file mode 100644
-index ...174e1ad 100644  
---- /dev/null
-+++ b/include/asm-powerpc/syscall.h
-@@ -0,0 +1,73 @@
-+/*
-+ * Access to user system call parameters and results
-+ *
-+ * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
-+ *
-+ * This copyrighted material is made available to anyone wishing to use,
-+ * modify, copy, or redistribute it subject to the terms and conditions
-+ * of the GNU General Public License v.2.
-+ *
-+ * See asm-generic/syscall.h for descriptions of what we must do here.
-+ */
-+
-+#ifndef _ASM_SYSCALL_H
-+#define _ASM_SYSCALL_H	1
-+
-+#include <linux/sched.h>
-+
-+static inline long syscall_get_nr(struct task_struct *task,
-+				  struct pt_regs *regs)
-+{
-+	return regs->trap == 0xc01 ? regs->gpr[0] : -1L;
-+}
-+
-+static inline void syscall_rollback(struct task_struct *task,
-+				    struct pt_regs *regs)
-+{
-+	regs->gpr[3] = regs->orig_gpr3;
-+}
-+
-+static inline long syscall_get_error(struct task_struct *task,
-+				     struct pt_regs *regs)
-+{
-+	return (regs->ccr & 0x1000) ? -regs->gpr[3] : 0;
-+}
-+
-+static inline long syscall_get_return_value(struct task_struct *task,
-+					    struct pt_regs *regs)
-+{
-+	return regs->gpr[3];
-+}
-+
-+static inline void syscall_set_return_value(struct task_struct *task,
-+					    struct pt_regs *regs,
-+					    int error, long val)
-+{
-+	if (error) {
-+		regs->ccr |= 0x1000L;
-+		regs->gpr[3] = -error;
-+	} else {
-+		regs->ccr &= ~0x1000L;
-+		regs->gpr[3] = val;
-+	}
-+}
-+
-+static inline void syscall_get_arguments(struct task_struct *task,
-+					 struct pt_regs *regs,
-+					 unsigned int i, unsigned int n,
-+					 unsigned long args[n])
-+{
-+	BUG_ON(i + n > 6);
-+	memcpy(args, &regs->gpr[3 + i], n * sizeof(args[0]));
-+}
-+
-+static inline void syscall_set_arguments(struct task_struct *task,
-+					 struct pt_regs *regs,
-+					 unsigned int i, unsigned int n,
-+					 const unsigned long args[n])
-+{
-+	BUG_ON(i + n > 6);
-+	memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0]));
-+}
-+
-+#endif	/* _ASM_SYSCALL_H */
-diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
-index e079e81..d0005e8 100644  
---- a/include/asm-powerpc/thread_info.h
-+++ b/include/asm-powerpc/thread_info.h
-@@ -116,6 +116,7 @@ static inline struct thread_info *curren
- #define TIF_SECCOMP		10	/* secure computing */
- #define TIF_RESTOREALL		11	/* Restore all regs (implies NOERROR) */
- #define TIF_NOERROR		12	/* Force successful syscall return */
-+#define TIF_NOTIFY_RESUME	13	/* callback before returning to user */
- #define TIF_FREEZE		14	/* Freezing for suspend */
- #define TIF_RUNLATCH		15	/* Is the runlatch enabled? */
- #define TIF_ABI_PENDING		16	/* 32/64 bit switch needed */
-@@ -133,12 +134,14 @@ static inline struct thread_info *curren
- #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
- #define _TIF_RESTOREALL		(1<<TIF_RESTOREALL)
- #define _TIF_NOERROR		(1<<TIF_NOERROR)
-+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
- #define _TIF_FREEZE		(1<<TIF_FREEZE)
- #define _TIF_RUNLATCH		(1<<TIF_RUNLATCH)
- #define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
- #define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
- 
--#define _TIF_USER_WORK_MASK	(_TIF_SIGPENDING | _TIF_NEED_RESCHED)
-+#define _TIF_USER_WORK_MASK	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
-+				 _TIF_NOTIFY_RESUME)
- #define _TIF_PERSYSCALL_MASK	(_TIF_RESTOREALL|_TIF_NOERROR)
- 
- /* Bits in local_flags */
-diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h
-index b163da7..91387fd 100644  
---- a/include/asm-sparc64/ptrace.h
-+++ b/include/asm-sparc64/ptrace.h
-@@ -146,6 +146,7 @@ do {	current_thread_info()->syscall_noer
- } while (0)
- #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
- #define instruction_pointer(regs) ((regs)->tpc)
-+#define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
- #define regs_return_value(regs) ((regs)->u_regs[UREG_I0])
- #ifdef CONFIG_SMP
- extern unsigned long profile_pc(struct pt_regs *);
-diff --git a/include/asm-sparc64/syscall.h b/include/asm-sparc64/syscall.h
-new file mode 100644
-index ...c00fb1a 100644  
---- /dev/null
-+++ b/include/asm-sparc64/syscall.h
-@@ -0,0 +1,70 @@
-+/*
-+ * Access to user system call parameters and results
-+ *
-+ * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
-+ *
-+ * This copyrighted material is made available to anyone wishing to use,
-+ * modify, copy, or redistribute it subject to the terms and conditions
-+ * of the GNU General Public License v.2.
-+ *
-+ * See asm-generic/syscall.h for descriptions of what we must do here.
-+ */
-+
-+#ifndef _ASM_SYSCALL_H
-+#define _ASM_SYSCALL_H	1
-+
-+#include <asm/ptrace.h>
-+struct task_struct;
-+
-+static inline long syscall_get_nr(struct task_struct *task,
-+				  struct pt_regs *regs)
-+{
-+	return pt_regs_is_syscall(regs) ? regs->u_regs[UREG_G1] : -1L;
-+}
-+
-+static inline long syscall_get_error(struct task_struct *task,
-+				     struct pt_regs *regs)
-+{
-+	if (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))
-+		return -regs->u_regs[UREG_I0];
-+	return 0;
-+}
-+
-+static inline long syscall_get_return_value(struct task_struct *task,
-+					    struct pt_regs *regs)
-+{
-+	return regs->u_regs[UREG_I0];
-+}
-+
-+static inline void syscall_set_return_value(struct task_struct *task,
-+					    struct pt_regs *regs,
-+					    int error, long val)
-+{
-+	if (error) {
-+		regs->tstate |= (TSTATE_XCARRY | TSTATE_ICARRY);
-+		regs->u_regs[UREG_I0] = -error;
-+	} else {
-+		regs->tstate &= ~(TSTATE_XCARRY | TSTATE_ICARRY);
-+		regs->u_regs[UREG_I0] = val;
-+	}
-+}
-+
-+static inline void syscall_get_arguments(struct task_struct *task,
-+					 struct pt_regs *regs,
-+					 unsigned int i, unsigned int n,
-+					 unsigned long args[n])
-+{
-+	BUG_ON(i + n > 6);
-+	memcpy(args, &regs->u_regs[UREG_I0 + i], n * sizeof(args[0]));
-+}
-+
-+static inline void syscall_set_arguments(struct task_struct *task,
-+					 struct pt_regs *regs,
-+					 unsigned int i, unsigned int n,
-+					 const unsigned long args[n])
-+{
-+	BUG_ON(i + n > 6);
-+	memcpy(&regs->u_regs[UREG_I0 + i], args, n * sizeof(args[0]));
-+}
-+
-+#endif	/* _ASM_SYSCALL_H */
-diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
-index e5873e3..a4d0147 100644  
---- a/include/asm-sparc64/thread_info.h
-+++ b/include/asm-sparc64/thread_info.h
-@@ -217,7 +217,7 @@ register struct thread_info *current_thr
-  *	 nop
-  */
- #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
--/* flags bit 1 is available */
-+#define TIF_NOTIFY_RESUME	1	/* callback before returning to user */
- #define TIF_SIGPENDING		2	/* signal pending */
- #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
- #define TIF_PERFCTR		4	/* performance counters active */
-@@ -237,6 +237,7 @@ register struct thread_info *current_thr
- #define TIF_POLLING_NRFLAG	14
- 
- #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
-+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
- #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
- #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
- #define _TIF_PERFCTR		(1<<TIF_PERFCTR)
-@@ -248,8 +249,9 @@ register struct thread_info *current_thr
- #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
- 
- #define _TIF_USER_WORK_MASK	((0xff << TI_FLAG_WSAVED_SHIFT) | \
--				 (_TIF_SIGPENDING | \
--				  _TIF_NEED_RESCHED | _TIF_PERFCTR))
-+				 _TIF_DO_NOTIFY_RESUME_MASK | \
-+				 _TIF_NEED_RESCHED | _TIF_PERFCTR)
-+#define _TIF_DO_NOTIFY_RESUME_MASK	(_TIF_NOTIFY_RESUME | _TIF_SIGPENDING)
- 
- /*
-  * Thread-synchronous status.
-diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h
-index 9f922b0..555e8c9 100644  
---- a/include/asm-x86/ptrace.h
-+++ b/include/asm-x86/ptrace.h
-@@ -211,6 +211,11 @@ static inline unsigned long frame_pointe
- 	return regs->bp;
- }
- 
-+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
-+{
-+	return regs->sp;
-+}
-+
- /*
-  * These are defined as per linux/ptrace.h, which see.
-  */
-diff --git a/include/asm-x86/syscall.h b/include/asm-x86/syscall.h
-new file mode 100644
-index ...7de35f0 100644  
---- /dev/null
-+++ b/include/asm-x86/syscall.h
-@@ -0,0 +1,210 @@
-+/*
-+ * Access to user system call parameters and results
-+ *
-+ * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
-+ *
-+ * This copyrighted material is made available to anyone wishing to use,
-+ * modify, copy, or redistribute it subject to the terms and conditions
-+ * of the GNU General Public License v.2.
-+ *
-+ * See asm-generic/syscall.h for descriptions of what we must do here.
-+ */
-+
-+#ifndef _ASM_SYSCALL_H
-+#define _ASM_SYSCALL_H	1
-+
-+#include <linux/sched.h>
-+
-+static inline long syscall_get_nr(struct task_struct *task,
-+				  struct pt_regs *regs)
-+{
-+	/*
-+	 * We always sign-extend a -1 value being set here,
-+	 * so this is always either -1L or a syscall number.
-+	 */
-+	return regs->orig_ax;
-+}
-+
-+static inline void syscall_rollback(struct task_struct *task,
-+				    struct pt_regs *regs)
-+{
-+	regs->ax = regs->orig_ax;
-+}
-+
-+static inline long syscall_get_error(struct task_struct *task,
-+				     struct pt_regs *regs)
-+{
-+	unsigned long error = regs->ax;
-+#ifdef CONFIG_IA32_EMULATION
-+	/*
-+	 * TS_COMPAT is set for 32-bit syscall entries and then
-+	 * remains set until we return to user mode.
-+	 */
-+	if (task_thread_info(task)->status & TS_COMPAT)
-+		/*
-+		 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
-+		 * and will match correctly in comparisons.
-+		 */
-+		error = (long) (int) error;
-+#endif
-+	return error >= -4095L ? error : 0;
-+}
-+
-+static inline long syscall_get_return_value(struct task_struct *task,
-+					    struct pt_regs *regs)
-+{
-+	return regs->ax;
-+}
-+
-+static inline void syscall_set_return_value(struct task_struct *task,
-+					    struct pt_regs *regs,
-+					    int error, long val)
-+{
-+	regs->ax = (long) error ?: val;
-+}
-+
-+#ifdef CONFIG_X86_32
-+
-+static inline void syscall_get_arguments(struct task_struct *task,
-+					 struct pt_regs *regs,
-+					 unsigned int i, unsigned int n,
-+					 unsigned long args[n])
-+{
-+	BUG_ON(i + n > 6);
-+	memcpy(args, &regs->bx + i, n * sizeof(args[0]));
-+}
-+
-+static inline void syscall_set_arguments(struct task_struct *task,
-+					 struct pt_regs *regs,
-+					 unsigned int i, unsigned int n,
-+					 const unsigned long args[n])
-+{
-+	BUG_ON(i + n > 6);
-+	memcpy(&regs->bx + i, args, n * sizeof(args[0]));
-+}
-+
-+#else	 /* CONFIG_X86_64 */
-+
-+static inline void syscall_get_arguments(struct task_struct *task,
-+					 struct pt_regs *regs,
-+					 unsigned int i, unsigned int n,
-+					 unsigned long *args)
-+{
-+# ifdef CONFIG_IA32_EMULATION
-+	if (task_thread_info(task)->status & TS_COMPAT)
-+		switch (i + n) {
-+		case 6:
-+			if (!n--) break;
-+			*args++ = regs->bp;
-+		case 5:
-+			if (!n--) break;
-+			*args++ = regs->di;
-+		case 4:
-+			if (!n--) break;
-+			*args++ = regs->si;
-+		case 3:
-+			if (!n--) break;
-+			*args++ = regs->dx;
-+		case 2:
-+			if (!n--) break;
-+			*args++ = regs->cx;
-+		case 1:
-+			if (!n--) break;
-+			*args++ = regs->bx;
-+		case 0:
-+			if (!n--) break;
-+		default:
-+			BUG();
-+			break;
-+		}
-+	else
-+# endif
-+		switch (i + n) {
-+		case 6:
-+			if (!n--) break;
-+			*args++ = regs->r9;
-+		case 5:
-+			if (!n--) break;
-+			*args++ = regs->r8;
-+		case 4:
-+			if (!n--) break;
-+			*args++ = regs->r10;
-+		case 3:
-+			if (!n--) break;
-+			*args++ = regs->dx;
-+		case 2:
-+			if (!n--) break;
-+			*args++ = regs->si;
-+		case 1:
-+			if (!n--) break;
-+			*args++ = regs->di;
-+		case 0:
-+			if (!n--) break;
-+		default:
-+			BUG();
-+			break;
-+		}
-+}
-+
-+static inline void syscall_set_arguments(struct task_struct *task,
-+					 struct pt_regs *regs,
-+					 unsigned int i, unsigned int n,
-+					 const unsigned long *args)
-+{
-+# ifdef CONFIG_IA32_EMULATION
-+	if (task_thread_info(task)->status & TS_COMPAT)
-+		switch (i + n) {
-+		case 6:
-+			if (!n--) break;
-+			regs->bp = *args++;
-+		case 5:
-+			if (!n--) break;
-+			regs->di = *args++;
-+		case 4:
-+			if (!n--) break;
-+			regs->si = *args++;
-+		case 3:
-+			if (!n--) break;
-+			regs->dx = *args++;
-+		case 2:
-+			if (!n--) break;
-+			regs->cx = *args++;
-+		case 1:
-+			if (!n--) break;
-+			regs->bx = *args++;
-+		case 0:
-+			if (!n--) break;
-+		default:
-+			BUG();
-+		}
-+	else
-+# endif
-+		switch (i + n) {
-+		case 6:
-+			if (!n--) break;
-+			regs->r9 = *args++;
-+		case 5:
-+			if (!n--) break;
-+			regs->r8 = *args++;
-+		case 4:
-+			if (!n--) break;
-+			regs->r10 = *args++;
-+		case 3:
-+			if (!n--) break;
-+			regs->dx = *args++;
-+		case 2:
-+			if (!n--) break;
-+			regs->si = *args++;
-+		case 1:
-+			if (!n--) break;
-+			regs->di = *args++;
-+		case 0:
-+			if (!n--) break;
-+		default:
-+			BUG();
-+		}
-+}
-+
-+#endif	/* CONFIG_X86_32 */
-+
-+#endif	/* _ASM_SYSCALL_H */
-diff --git a/include/asm-x86/thread_info_32.h b/include/asm-x86/thread_info_32.h
-index 3267d9c..975e2b1 100644  
---- a/include/asm-x86/thread_info_32.h
-+++ b/include/asm-x86/thread_info_32.h
-@@ -131,6 +131,7 @@ static inline struct thread_info *curren
- #define TIF_SYSCALL_EMU		5	/* syscall emulation active */
- #define TIF_SYSCALL_AUDIT	6	/* syscall auditing active */
- #define TIF_SECCOMP		7	/* secure computing */
-+#define TIF_NOTIFY_RESUME	8	/* callback before returning to user */
- #define TIF_HRTICK_RESCHED	9	/* reprogram hrtick timer */
- #define TIF_MEMDIE		16
- #define TIF_DEBUG		17	/* uses debug registers */
-@@ -150,6 +151,7 @@ static inline struct thread_info *curren
- #define _TIF_SYSCALL_EMU	(1 << TIF_SYSCALL_EMU)
- #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
- #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
-+#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
- #define _TIF_HRTICK_RESCHED	(1 << TIF_HRTICK_RESCHED)
- #define _TIF_DEBUG		(1 << TIF_DEBUG)
- #define _TIF_IO_BITMAP		(1 << TIF_IO_BITMAP)
-diff --git a/include/asm-x86/thread_info_64.h b/include/asm-x86/thread_info_64.h
-index a531e79..f1281a7 100644  
---- a/include/asm-x86/thread_info_64.h
-+++ b/include/asm-x86/thread_info_64.h
-@@ -103,6 +103,7 @@ static inline struct thread_info *stack_
-  * Warning: layout of LSW is hardcoded in entry.S
-  */
- #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
-+#define TIF_NOTIFY_RESUME	1	/* callback before returning to user */
- #define TIF_SIGPENDING		2	/* signal pending */
- #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
- #define TIF_SINGLESTEP		4	/* reenable singlestep on user return*/
-@@ -127,6 +128,7 @@ static inline struct thread_info *stack_
- #define TIF_NOTSC		28	/* TSC is not accessible in userland */
- 
- #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
-+#define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
- #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
- #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
- #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
-@@ -165,7 +167,7 @@ static inline struct thread_info *stack_
- #define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP)
- 
- #define _TIF_DO_NOTIFY_MASK						\
--	(_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_HRTICK_RESCHED)
-+	(_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_HRTICK_RESCHED|_TIF_NOTIFY_RESUME)
- 
- /* flags to check in __switch_to() */
- #define _TIF_WORK_CTXSW							\
 diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
-index f98501b..c6d85c5 100644  
+index c6f5f9d..fd31756 100644  
 --- a/include/linux/ptrace.h
 +++ b/include/linux/ptrace.h
-@@ -117,6 +117,74 @@ static inline void ptrace_unlink(struct 
+@@ -121,6 +121,74 @@ static inline void ptrace_unlink(struct 
  int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data);
  int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data);
  
@@ -1913,7 +547,7 @@
  #ifndef force_successful_syscall_return
  /*
   * System call handlers that, upon successful completion, need to return a
-@@ -242,6 +310,10 @@ static inline void user_enable_block_ste
+@@ -246,6 +314,10 @@ static inline void user_enable_block_ste
  #define arch_ptrace_stop(code, info)		do { } while (0)
  #endif
  
@@ -1925,10 +559,10 @@
  
  #endif
 diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 75145b7..c77eeb8 100644  
+index dc7e592..fdcd427 100644  
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
-@@ -1779,7 +1779,7 @@ extern int kill_pid_info_as_uid(int, str
+@@ -1795,7 +1795,7 @@ extern int kill_pid_info_as_uid(int, str
  extern int kill_pgrp(struct pid *pid, int sig, int priv);
  extern int kill_pid(struct pid *pid, int sig, int priv);
  extern int kill_proc_info(int, struct siginfo *, pid_t);
@@ -1937,7 +571,7 @@
  extern void force_sig(int, struct task_struct *);
  extern void force_sig_specific(int, struct task_struct *);
  extern int send_sig(int, struct task_struct *, int);
-@@ -1866,9 +1866,13 @@ extern void set_task_comm(struct task_st
+@@ -1882,9 +1882,13 @@ extern void set_task_comm(struct task_st
  extern char *get_task_comm(char *to, struct task_struct *tsk);
  
  #ifdef CONFIG_SMP
@@ -1955,7 +589,7 @@
  #define next_task(p)	list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks)
 diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
 new file mode 100644
-index ...61d4ca4 100644  
+index ...589f429 100644  
 --- /dev/null
 +++ b/include/linux/tracehook.h
 @@ -0,0 +1,575 @@
@@ -2024,7 +658,7 @@
 + */
 +static inline int tracehook_expect_breakpoints(struct task_struct *task)
 +{
-+	return (task_ptrace(task) & PT_PTRACED);
++	return (task_ptrace(task) & PT_PTRACED) != 0;
 +}
 +
 +/*
@@ -2172,7 +806,7 @@
 + */
 +static inline void tracehook_report_exit(long *exit_code)
 +{
-+	ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXIT, *exit_code);
++	ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code);
 +}
 +
 +/**
@@ -2360,7 +994,7 @@
 +						    int sig,
 +						    void __user *handler)
 +{
-+	return (task_ptrace(task) & PT_PTRACED);
++	return (task_ptrace(task) & PT_PTRACED) != 0;
 +}
 +
 +/**
@@ -2381,7 +1015,7 @@
 +						  int sig,
 +						  void __user *handler)
 +{
-+	return (task_ptrace(task) & PT_PTRACED);
++	return (task_ptrace(task) & PT_PTRACED) != 0;
 +}
 +
 +/**
@@ -2535,10 +1169,10 @@
 +
 +#endif	/* <linux/tracehook.h> */
 diff --git a/kernel/exit.c b/kernel/exit.c
-index fa7b700..a0225e2 100644  
+index 93d2711..78c6307 100644  
 --- a/kernel/exit.c
 +++ b/kernel/exit.c
-@@ -45,6 +45,7 @@
+@@ -46,6 +46,7 @@
  #include <linux/resource.h>
  #include <linux/blkdev.h>
  #include <linux/task_io_accounting_ops.h>
@@ -2546,7 +1180,7 @@
  
  #include <asm/uaccess.h>
  #include <asm/unistd.h>
-@@ -151,27 +152,17 @@ static void delayed_put_task_struct(stru
+@@ -152,27 +153,17 @@ static void delayed_put_task_struct(stru
  	put_task_struct(container_of(rhp, struct task_struct, rcu));
  }
  
@@ -2576,7 +1210,7 @@
  	__exit_signal(p);
  
  	/*
-@@ -193,6 +184,13 @@ repeat:
+@@ -194,6 +185,13 @@ repeat:
  		 * that case.
  		 */
  		zap_leader = task_detached(leader);
@@ -2590,7 +1224,7 @@
  	}
  
  	write_unlock_irq(&tasklist_lock);
-@@ -862,7 +860,8 @@ static void forget_original_parent(struc
+@@ -863,7 +861,8 @@ static void forget_original_parent(struc
   */
  static void exit_notify(struct task_struct *tsk, int group_dead)
  {
@@ -2600,7 +1234,7 @@
  
  	/*
  	 * This does two things:
-@@ -899,22 +898,11 @@ static void exit_notify(struct task_stru
+@@ -900,22 +899,11 @@ static void exit_notify(struct task_stru
  	    !capable(CAP_KILL))
  		tsk->exit_signal = SIGCHLD;
  
@@ -2628,7 +1262,7 @@
  
  	/* mt-exec, de_thread() is waiting for us */
  	if (thread_group_leader(tsk) &&
-@@ -924,8 +912,10 @@ static void exit_notify(struct task_stru
+@@ -925,8 +913,10 @@ static void exit_notify(struct task_stru
  
  	write_unlock_irq(&tasklist_lock);
  
@@ -2640,7 +1274,7 @@
  		release_task(tsk);
  }
  
-@@ -1004,10 +994,7 @@ NORET_TYPE void do_exit(long code)
+@@ -1005,10 +995,7 @@ NORET_TYPE void do_exit(long code)
  	if (unlikely(!tsk->pid))
  		panic("Attempted to kill the idle task!");
  
@@ -2653,10 +1287,10 @@
  	/*
  	 * We're taking recursive faults here in do_exit. Safest is to just
 diff --git a/kernel/fork.c b/kernel/fork.c
-index df8fe06..37b5be0 100644  
+index adefc11..5345b7d 100644  
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
-@@ -54,6 +54,7 @@
+@@ -55,6 +55,7 @@
  #include <linux/tty.h>
  #include <linux/proc_fs.h>
  #include <linux/blkdev.h>
@@ -2664,7 +1298,7 @@
  
  #include <asm/pgtable.h>
  #include <asm/pgalloc.h>
-@@ -832,8 +833,7 @@ static void copy_flags(unsigned long clo
+@@ -833,8 +834,7 @@ static void copy_flags(unsigned long clo
  
  	new_flags &= ~PF_SUPERPRIV;
  	new_flags |= PF_FORKNOEXEC;
@@ -2674,7 +1308,7 @@
  	p->flags = new_flags;
  	clear_freeze_flag(p);
  }
-@@ -874,7 +874,8 @@ static struct task_struct *copy_process(
+@@ -875,7 +875,8 @@ static struct task_struct *copy_process(
  					struct pt_regs *regs,
  					unsigned long stack_size,
  					int __user *child_tidptr,
@@ -2684,7 +1318,7 @@
  {
  	int retval;
  	struct task_struct *p;
-@@ -1124,8 +1125,6 @@ static struct task_struct *copy_process(
+@@ -1125,8 +1126,6 @@ static struct task_struct *copy_process(
  	 */
  	p->group_leader = p;
  	INIT_LIST_HEAD(&p->thread_group);
@@ -2693,7 +1327,7 @@
  
  	/* Now that the task is set up, run cgroup callbacks if
  	 * necessary. We need to run them before the task is visible
-@@ -1156,7 +1155,6 @@ static struct task_struct *copy_process(
+@@ -1157,7 +1156,6 @@ static struct task_struct *copy_process(
  		p->real_parent = current->real_parent;
  	else
  		p->real_parent = current;
@@ -2701,7 +1335,7 @@
  
  	spin_lock(&current->sighand->siglock);
  
-@@ -1198,8 +1196,7 @@ static struct task_struct *copy_process(
+@@ -1199,8 +1197,7 @@ static struct task_struct *copy_process(
  
  	if (likely(p->pid)) {
  		list_add_tail(&p->sibling, &p->real_parent->children);
@@ -2711,7 +1345,7 @@
  
  		if (thread_group_leader(p)) {
  			if (clone_flags & CLONE_NEWPID)
-@@ -1284,29 +1281,13 @@ struct task_struct * __cpuinit fork_idle
+@@ -1285,29 +1282,13 @@ struct task_struct * __cpuinit fork_idle
  	struct pt_regs regs;
  
  	task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
@@ -2742,7 +1376,7 @@
  /*
   *  Ok, this is the main fork-routine.
   *
-@@ -1341,14 +1322,14 @@ long do_fork(unsigned long clone_flags,
+@@ -1342,14 +1323,14 @@ long do_fork(unsigned long clone_flags,
  		}
  	}
  
@@ -2763,7 +1397,7 @@
  	/*
  	 * Do this prior waking up the new thread - the thread pointer
  	 * might get invalid after that point, if the thread exits quickly.
-@@ -1366,32 +1347,35 @@ long do_fork(unsigned long clone_flags,
+@@ -1367,32 +1348,35 @@ long do_fork(unsigned long clone_flags,
  			init_completion(&vfork);
  		}
  
@@ -2814,7 +1448,7 @@
  	} else {
  		nr = PTR_ERR(p);
 diff --git a/kernel/kthread.c b/kernel/kthread.c
-index bd1b9ea..1869162 100644  
+index ac3fb73..88538db 100644  
 --- a/kernel/kthread.c
 +++ b/kernel/kthread.c
 @@ -176,7 +176,7 @@ void kthread_bind(struct task_struct *k,
@@ -2827,7 +1461,7 @@
  	k->cpus_allowed = cpumask_of_cpu(cpu);
  	k->rt.nr_cpus_allowed = 1;
 diff --git a/kernel/ptrace.c b/kernel/ptrace.c
-index acf80a4..ef66127 100644  
+index 8392a9d..082b3fc 100644  
 --- a/kernel/ptrace.c
 +++ b/kernel/ptrace.c
 @@ -107,7 +107,7 @@ int ptrace_check_attach(struct task_stru
@@ -2840,10 +1474,10 @@
  	/* All systems go.. */
  	return ret;
 diff --git a/kernel/sched.c b/kernel/sched.c
-index 4e2f603..102d634 100644  
+index 6acf749..dfb65bd 100644  
 --- a/kernel/sched.c
 +++ b/kernel/sched.c
-@@ -1765,16 +1765,24 @@ migrate_task(struct task_struct *p, int 
+@@ -1867,16 +1867,24 @@ migrate_task(struct task_struct *p, int 
  /*
   * wait_task_inactive - wait for a thread to unschedule.
   *
@@ -2869,7 +1503,7 @@
  	struct rq *rq;
  
  	for (;;) {
-@@ -1797,8 +1805,11 @@ void wait_task_inactive(struct task_stru
+@@ -1899,8 +1907,11 @@ void wait_task_inactive(struct task_stru
  		 * return false if the runqueue has changed and p
  		 * is actually now running somewhere else!
  		 */
@@ -2882,7 +1516,7 @@
  
  		/*
  		 * Ok, time to look more closely! We need the rq
-@@ -1808,9 +1819,21 @@ void wait_task_inactive(struct task_stru
+@@ -1910,9 +1921,21 @@ void wait_task_inactive(struct task_stru
  		rq = task_rq_lock(p, &flags);
  		running = task_running(rq, p);
  		on_rq = p->se.on_rq;
@@ -2904,7 +1538,7 @@
  		 * Was it really running after all now that we
  		 * checked with the proper locks actually held?
  		 *
-@@ -1842,6 +1865,8 @@ void wait_task_inactive(struct task_stru
+@@ -1944,6 +1967,8 @@ void wait_task_inactive(struct task_stru
  		 */
  		break;
  	}
@@ -3170,10 +1804,10 @@
  			sigaddset(&mask, sig);
  			rm_from_queue_full(&mask, &t->signal->shared_pending);
 diff --git a/lib/Makefile b/lib/Makefile
-index 74b0cfb..62dfd16 100644  
+index 818c4d4..c0bad7f 100644  
 --- a/lib/Makefile
 +++ b/lib/Makefile
-@@ -72,6 +72,8 @@ lib-$(CONFIG_GENERIC_BUG) += bug.o
+@@ -78,6 +78,8 @@ lib-$(CONFIG_GENERIC_BUG) += bug.o
  
  obj-$(CONFIG_HAVE_LMB) += lmb.o
  
@@ -3286,10 +1920,10 @@
  
  	return vm_flags;
 diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
-index 1c864c0..f92c6af 100644  
+index 63f131f..3481cde 100644  
 --- a/security/selinux/hooks.c
 +++ b/security/selinux/hooks.c
-@@ -24,7 +24,7 @@
+@@ -25,7 +25,7 @@
  
  #include <linux/init.h>
  #include <linux/kernel.h>
@@ -3298,7 +1932,7 @@
  #include <linux/errno.h>
  #include <linux/sched.h>
  #include <linux/security.h>
-@@ -1910,22 +1910,6 @@ static int selinux_vm_enough_memory(stru
+@@ -1971,22 +1971,6 @@ static int selinux_vm_enough_memory(stru
  	return __vm_enough_memory(mm, pages, cap_sys_admin);
  }
  
@@ -3321,7 +1955,7 @@
  /* binprm security operations */
  
  static int selinux_bprm_alloc_security(struct linux_binprm *bprm)
-@@ -2177,7 +2161,7 @@ static void selinux_bprm_apply_creds(str
+@@ -2238,7 +2222,7 @@ static void selinux_bprm_apply_creds(str
  			u32 ptsid = 0;
  
  			rcu_read_lock();
@@ -3330,7 +1964,7 @@
  			if (likely(tracer != NULL)) {
  				sec = tracer->security;
  				ptsid = sec->sid;
-@@ -5205,7 +5189,7 @@ static int selinux_setprocattr(struct ta
+@@ -5247,7 +5231,7 @@ static int selinux_setprocattr(struct ta
  		   Otherwise, leave SID unchanged and fail. */
  		task_lock(p);
  		rcu_read_lock();

linux-2.6-utrace.patch:

View full diff with command:
/usr/bin/cvs -f diff  -kk -u -N -r 1.82 -r 1.83 linux-2.6-utrace.patch
Index: linux-2.6-utrace.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-utrace.patch,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -r1.82 -r1.83
--- linux-2.6-utrace.patch	14 Jul 2008 19:38:29 -0000	1.82
+++ linux-2.6-utrace.patch	24 Jul 2008 08:28:26 -0000	1.83
@@ -1,17 +1,16 @@
  Documentation/DocBook/Makefile    |    2 +-
- Documentation/DocBook/utrace.tmpl |   21 +
- Documentation/utrace.txt          |  579 ++++++++++
+ Documentation/DocBook/utrace.tmpl |  475 ++++++++
  fs/proc/array.c                   |    3 +
- include/linux/ptrace.h            |   15 +
+ include/linux/ptrace.h            |   21 +
  include/linux/sched.h             |    6 +
- include/linux/tracehook.h         |   60 +
- include/linux/utrace.h            |  534 +++++++++
- init/Kconfig                      |   28 +
+ include/linux/tracehook.h         |   62 +
+ include/linux/utrace.h            |  610 ++++++++++
+ init/Kconfig                      |   27 +
  kernel/Makefile                   |    1 +
- kernel/ptrace.c                   |  542 +++++++++-
+ kernel/ptrace.c                   |  578 ++++++++++-
  kernel/signal.c                   |   14 +-
- kernel/utrace.c                   | 2211 +++++++++++++++++++++++++++++++++++++
- 13 files changed, 4012 insertions(+), 4 deletions(-)
+ kernel/utrace.c                   | 2278 +++++++++++++++++++++++++++++++++++++
+ 12 files changed, 4070 insertions(+), 7 deletions(-)
 
 diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
 index 0eb0d02..49a78b7 100644  
@@ -28,616 +27,485 @@
  	    gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
 diff --git a/Documentation/DocBook/utrace.tmpl b/Documentation/DocBook/utrace.tmpl
 new file mode 100644
-index ...8dfaa91 100644  
+index ...3e47524 100644  
 --- /dev/null
 +++ b/Documentation/DocBook/utrace.tmpl
-@@ -0,0 +1,21 @@
+@@ -0,0 +1,475 @@
 +<?xml version="1.0" encoding="UTF-8"?>
 +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-+	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
++"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
 +
 +<book id="utrace">
-+ <bookinfo>
-+  <title>The utrace User Debugging Infrastructure</title>
-+ </bookinfo>
++  <bookinfo>
++    <title>The utrace User Debugging Infrastructure</title>
++  </bookinfo>
++
++  <toc></toc>
++
++  <chapter id="concepts"><title>utrace concepts</title>
++
++  <sect1 id="intro"><title>Introduction</title>
++
++  <para>
++    <application>utrace</application> is infrastructure code for tracing
++    and controlling user threads.  This is the foundation for writing
++    tracing engines, which can be loadable kernel modules.
++  </para>
++
++  <para>
++    The basic actors in <application>utrace</application> are the thread
++    and the tracing engine.  A tracing engine is some body of code that
++    calls into the <filename><linux/utrace.h></filename>
++    interfaces, represented by a <structname>struct
++    utrace_engine_ops</structname>.  (Usually it's a kernel module,
++    though the legacy <function>ptrace</function> support is a tracing
++    engine that is not in a kernel module.)  The interface operates on
++    individual threads (<structname>struct task_struct</structname>).
++    If an engine wants to treat several threads as a group, that is up
++    to its higher-level code.
++  </para>
++
++  <para>
++    Tracing begins by attaching an engine to a thread, using
++    <function>utrace_attach</function>.  If successful, it returns a
++    pointer that is the handle used in all other calls.
++  </para>
++
++  </sect1>
++
++  <sect1 id="callbacks"><title>Events and Callbacks</title>
++
++  <para>
++    An attached engine does nothing by default.  An engine makes something
++    happen by requesting callbacks via <function>utrace_set_events</function>
++    and poking the thread with <function>utrace_control</function>.
++    The synchronization issues related to these two calls
++    are discussed further below in <xref linkend="teardown"/>.
++  </para>
++
++  <para>
++    Events are specified using the macro
++    <constant>UTRACE_EVENT(<replaceable>type</replaceable>)</constant>.
++    Each event type is associated with a callback in <structname>struct
++    utrace_engine_ops</structname>.  A tracing engine can leave unused
++    callbacks <constant>NULL</constant>.  The only callbacks required
++    are those used by the event flags it sets.
++  </para>
++
++  <para>
++    Many engines can be attached to each thread.  When a thread has an
++    event, each engine gets a callback if it has set the event flag for
++    that event type.  Engines are called in the order they attached.
++  </para>
++
++  <para>
++    Event reporting callbacks have details particular to the event type,
++    but are all called in similar environments and have the same
++    constraints.  Callbacks are made from safe points, where no locks
++    are held, no special resources are pinned (usually), and the
++    user-mode state of the thread is accessible.  So, callback code has
++    a pretty free hand.  But to be a good citizen, callback code should
++    never block for long periods.  It is fine to block in
++    <function>kmalloc</function> and the like, but never wait for i/o or
++    for user mode to do something.  If you need the thread to wait, use
++    <constant>UTRACE_STOP</constant> and return from the callback
++    quickly.  When your i/o finishes or whatever, you can use
++    <function>utrace_control</function> to resume the thread.
++  </para>
++
++  </sect1>
++
++  <sect1 id="stopping"><title>Stopping Safely</title>
++
++  <para>
++    Well-behaved callbacks are important to maintain two essential
++    properties of the interface.  The first of these is that unrelated
++    tracing engines not interfere with each other.  If your engine's
++    event callback does not return quickly, then another engine won't
++    get the event notification in a timely manner.  The second important
++    property is that tracing be as noninvasive as possible to the normal
++    operation of the system overall and of the traced thread in
++    particular.  That is, attached tracing engines should not perturb a
++    thread's behavior, except to the extent that changing its
++    user-visible state is explicitly what you want to do.  (Obviously
++    some perturbation is unavoidable, primarily timing changes, ranging
++    from small delays due to the overhead of tracing, to arbitrary
++    pauses in user code execution when a user stops a thread with a
++    debugger for examination.)  Even when you explicitly want the
++    pertrubation of making the traced thread block, just blocking
++    directly in your callback has more unwanted effects.  For example,
++    the <constant>CLONE</constant> event callbacks are called when the
++    new child thread has been created but not yet started running; the
++    child can never be scheduled until the <constant>CLONE</constant>
++    tracing callbacks return.  (This allows engines tracing the parent
++    to attach to the child.)  If a <constant>CLONE</constant> event
++    callback blocks the parent thread, it also prevents the child thread
++    from running (even to process a <constant>SIGKILL</constant>).  If
++    what you want is to make both the parent and child block, then use
++    <function>utrace_attach</function> on the child and then use
++    <constant>UTRACE_STOP</constant> on both threads.  A more crucial
++    problem with blocking in callbacks is that it can prevent
++    <constant>SIGKILL</constant> from working.  A thread that is
++    blocking due to <constant>UTRACE_STOP</constant> will still wake up
++    and die immediately when sent a <constant>SIGKILL</constant>, as all
++    threads should.  Relying on the <application>utrace</application>
++    infrastructure rather than on private synchronization calls in event
++    callbacks is an important way to help keep tracing robustly
++    noninvasive.
++  </para>
++
++  <para>
++    To control another thread and access its state, it must be stopped
++    with <constant>UTRACE_STOP</constant>.  This means that it is
++    stopped and won't start running again while we access it.  When a
++    thread is not already stopped, <function>utrace_control</function>
++    returns <constant>-EINPROGRESS</constant> and an engine must wait
++    for an event callback when the thread is ready to stop.  The thread
++    may be running on another CPU or may be blocked.  When it is ready
++    to be examined, it will make callbacks to engines that set the
++    <constant>UTRACE_EVENT(QUIESCE)</constant> event bit.  To wake up an
++    interruptible wait, use <constant>UTRACE_INTERRUPT</constant>.
++  </para>
++
++  <para>
++    As long as some engine has used <constant>UTRACE_STOP</constant> and
++    not called <function>utrace_control</function> to resume the thread,
++    then the thread will remain stopped.  <constant>SIGKILL</constant>
++    will wake it up, but it will not run user code.  When the stop is
++    cleared with <function>utrace_control</function> or a callback
++    return value, the thread starts running again.
++    (See also <xref linkend="teardown"/>.)
++  </para>
++
++  </sect1>
++
++  <sect1 id="teardown"><title>Teardown Races</title>
++
++  <para>
++    Ordinarily synchronization issues for tracing engines are kept fairly
[...2251 lines suppressed...]
++	     (utrace->reap && ((old_flags & ~events) & UTRACE_EVENT(REAP))))) {
 +		spin_unlock(&utrace->lock);
 +		return -EALREADY;
 +	}
@@ -2896,7 +2951,7 @@
 +	 * and really is quiescent now in its existing job control stop.
 +	 */
 +	if (!utrace->stopped &&
-+	    ((set_utrace_flags &~ old_utrace_flags) & UTRACE_EVENT(JCTL))) {
++	    ((set_utrace_flags & ~old_utrace_flags) & UTRACE_EVENT(JCTL))) {
 +		sighand = lock_task_sighand(target, &flags);
 +		if (likely(sighand)) {
 +			if (task_is_stopped(target))
@@ -2915,7 +2970,7 @@
 +	 * knows positively that utrace_report_death() will be called or
 +	 * that it won't.
 +	 */
-+	if ((set_utrace_flags &~ old_utrace_flags) & DEATH_EVENTS) {
++	if ((set_utrace_flags & ~old_utrace_flags) & DEATH_EVENTS) {
 +		read_lock(&tasklist_lock);
 +		if (unlikely(target->exit_state)) {
 +			read_unlock(&tasklist_lock);
@@ -3048,14 +3103,16 @@
 +	struct utrace_attached_engine *engine, *next;
 +	unsigned long flags = 0;
 +
++	splice_attaching(utrace);
++
 +	/*
 +	 * Update the set of events of interest from the union
 +	 * of the interests of the remaining tracing engines.
 +	 * For any engine marked detached, remove it from the list.
 +	 */
-+	list_for_each_entry_safe(engine, next, &utrace->engines, entry) {
++	list_for_each_entry_safe(engine, next, &utrace->attached, entry) {
 +		if (engine->ops == &utrace_detached_ops) {
-+			list_del_rcu(&engine->entry);
++			list_del(&engine->entry);
 +			continue;
 +		}
 +
@@ -3129,8 +3186,8 @@
 + * again if it was stopped and no longer has any attached engines
 + * that want it stopped.
 + *
-+ * If the report_reap() callback may already have begun, this fails
-+ * with -%ESRCH.  If the report_deeath() callback may already have
++ * If the @report_reap callback may already have begun, this fails
++ * with -%ESRCH.  If the @report_deeath callback may already have
 + * begun, this fails with -%EALREADY.
 + *
 + * If @target is not already stopped, then a callback to this engine
@@ -3141,8 +3198,8 @@
 + * to the @engine->ops vector will be made.
 + *
 + * The only exception is %SIGKILL (and exec or group-exit by another
-+ * thread in the group), which can cause asynchronous report_death()
-+ * and/or report_reap() callbacks even when %UTRACE_STOP was used.
++ * thread in the group), which can cause asynchronous @report_death
++ * and/or @report_reap callbacks even when %UTRACE_STOP was used.
 + * (In that event, this fails with -%ESRCH or -%EALREADY, see above.)
 + *
 + * UTRACE_STOP:
@@ -3154,14 +3211,14 @@
 + * another thread in the same thread group).
 + *
 + * This returns -%EINPROGRESS if @target is not already stopped.
-+ * Then the effect is like %UTRACE_REPORT.  A report_quiesce() or
-+ * report_signal() callback will be made soon.  Your callback can
++ * Then the effect is like %UTRACE_REPORT.  A @report_quiesce or
++ * @report_signal callback will be made soon.  Your callback can
 + * then return %UTRACE_STOP to keep @target stopped.
 + *
 + * This does not interrupt system calls in progress, including ones
 + * that sleep for a long time.  For that, use %UTRACE_INTERRUPT.
 + * To interrupt system calls and then keep @target stopped, your
-+ * report_signal() callback can return %UTRACE_STOP.
++ * @report_signal callback can return %UTRACE_STOP.
 + *
 + * UTRACE_RESUME:
 + *
@@ -3173,7 +3230,7 @@
 + * UTRACE_REPORT:
 + *
 + * This is like %UTRACE_RESUME, but also ensures that there will be
-+ * a report_quiesce() or report_signal() callback made soon.  If
++ * a @report_quiesce or @report_signal callback made soon.  If
 + * @target had been stopped, then there will be a callback before it
 + * resumes running normally.  If another engine is keeping @target
 + * stopped, then there might be no callbacks until all engines let
@@ -3182,14 +3239,14 @@
 + * UTRACE_INTERRUPT:
 + *
 + * This is like %UTRACE_REPORT, but ensures that @target will make a
-+ * report_signal() callback before it resumes or delivers signals.
++ * @report_signal callback before it resumes or delivers signals.
 + * If @target was in a system call or about to enter one, work in
 + * progress will be interrupted as if by %SIGSTOP.  If another
 + * engine is keeping @target stopped, then there might be no
 + * callbacks until all engines let it resume.
 + *
 + * This gives @engine an opportunity to introduce a forced signal
-+ * disposition via its report_signal() callback.
++ * disposition via its @report_signal callback.
 + *
 + * UTRACE_SINGLESTEP:
 + *
@@ -3204,8 +3261,8 @@
 + * more callbacks made to any engine before returning to user mode,
 + * then the resume action is chosen only by the last set of callbacks.
 + * To be sure, enable %UTRACE_EVENT(%QUIESCE) and look for the
-+ * report_quiesce() callback with a zero event mask, or the
-+ * report_signal() callback with %UTRACE_SIGNAL_REPORT.
++ * @report_quiesce callback with a zero event mask, or the
++ * @report_signal callback with %UTRACE_SIGNAL_REPORT.
 + *
 + * UTRACE_BLOCKSTEP:
 + *
@@ -3375,7 +3432,8 @@
 +	return ret;
 +}
 +EXPORT_SYMBOL_GPL(utrace_control);
-+
++
++
 +/*
 + * This is local state used for reporting loops, perhaps optimized away.
 + */
@@ -3399,6 +3457,7 @@
 +	if (utrace->report) {
 +		spin_lock(&utrace->lock);
 +		utrace->report = 0;
++		splice_attaching(utrace);
 +		spin_unlock(&utrace->lock);
 +	}
 +}
@@ -3543,7 +3602,7 @@
 +		struct utrace_attached_engine *engine, *next;		      \
 +		const struct utrace_engine_ops *ops;			      \
 +		list_for_each_entry_safe(engine, next,			      \
-+					 &utrace->engines, entry) {	      \
++					 &utrace->attached, entry) {	      \
 +			ops = start_callback(utrace, report, engine, task,    \
 +					     event);			      \
 +			if (!ops)					      \
@@ -3865,7 +3924,7 @@
 +	 */
 +	start_report(utrace);
 +
-+	list_for_each_entry_safe(engine, next, &utrace->engines, entry)
++	list_for_each_entry_safe(engine, next, &utrace->attached, entry)
 +		start_callback(utrace, &report, engine, task, 0);
 +
 +	/*
@@ -3950,6 +4009,8 @@
 +			return -1;
 +		}
 +
++		splice_attaching(utrace);
++
 +		if (unlikely(!utrace->interrupt) && unlikely(!utrace->report))
 +			action = UTRACE_SIGNAL_IGN;
 +		else if (utrace->signal_handler)
@@ -4079,7 +4140,7 @@
 +	/*
 +	 * This reporting pass chooses what signal disposition we'll act on.
 +	 */
-+	list_for_each_entry_safe(engine, next, &utrace->engines, entry) {
++	list_for_each_entry_safe(engine, next, &utrace->attached, entry) {
 +		/*
 +		 * This pairs with the barrier in mark_engine_detached(),
 +		 * see start_callback() comments.
@@ -4262,7 +4323,8 @@
 +
 +	spin_unlock(&utrace->lock);
 +}
-+
++
++
 +/**
 + * utrace_prepare_examine - prepare to examine thread state
 + * @target:		thread of interest, a &struct task_struct pointer
@@ -4382,7 +4444,7 @@
 +		struct list_head *pos, *next;
 +		struct utrace_attached_engine *engine;
 +		const struct utrace_engine_ops *ops;
-+		list_for_each_safe(pos, next, &utrace->engines) {
++		list_for_each_safe(pos, next, &utrace->attached) {
 +			engine = list_entry(pos, struct utrace_attached_engine,
 +					    entry);
 +			ops = rcu_dereference(engine->ops);
@@ -4408,7 +4470,7 @@
 +	const struct utrace_engine_ops *ops;
 +	int unsafe = 0;
 +
-+	list_for_each_entry_safe(engine, next, &utrace->engines, entry) {
++	list_for_each_entry_safe(engine, next, &utrace->attached, entry) {
 +		ops = rcu_dereference(engine->ops);
 +		if (ops->unsafe_exec)
 +			unsafe |= (*ops->unsafe_exec)(engine, task);


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/sources,v
retrieving revision 1.836
retrieving revision 1.837
diff -u -r1.836 -r1.837
--- sources	23 Jul 2008 19:51:09 -0000	1.836
+++ sources	24 Jul 2008 08:28:26 -0000	1.837
@@ -1,2 +1,2 @@
 5169d01c405bc3f866c59338e217968c  linux-2.6.26.tar.bz2
-5de8b6532393677ffa0ceb647213370d  patch-2.6.26-git10.bz2
+31df4b444a2404677d0003611190f417  patch-2.6.26-git11.bz2


Index: upstream
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/upstream,v
retrieving revision 1.753
retrieving revision 1.754
diff -u -r1.753 -r1.754
--- upstream	23 Jul 2008 19:51:09 -0000	1.753
+++ upstream	24 Jul 2008 08:28:26 -0000	1.754
@@ -1,2 +1,2 @@
 linux-2.6.26.tar.bz2
-patch-2.6.26-git10.bz2
+patch-2.6.26-git11.bz2


--- linux-2.6-ptrace-cleanup.patch DELETED ---


--- patch-2.6.26-git10.bz2.sign DELETED ---




More information about the fedora-extras-commits mailing list