---
 arch/Kconfig                            |    4 +
 arch/mips/Kconfig                       |   18 +----
 arch/mips/kernel/ptrace.c               |    5 -
 arch/powerpc/Kconfig                    |   18 +----
 arch/powerpc/include/asm/thread_info.h  |    4 +-
 arch/powerpc/kernel/ptrace.c            |    3 -
 arch/sh/Kconfig                         |   17 +----
 arch/sh/include/asm/thread_info.h       |    4 +-
 arch/sh/kernel/ptrace_32.c              |    3 -
 arch/sh/kernel/ptrace_64.c              |    3 -
 arch/sparc/include/asm/thread_info_64.h |    3 +-
 arch/x86/Kconfig                        |   17 +----
 arch/x86/kernel/entry_32.S              |    8 +-
 arch/x86/kernel/ptrace.c                |    4 -
 include/linux/sched.h                   |    2 -
 include/linux/seccomp.h                 |   14 ---
 init/Kconfig                            |   18 ++++
 kernel/seccomp.c                        |  148 ++++++++++++++++++-------------
 18 files changed, 118 insertions(+), 175 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 550dab2..f809f07 100644  
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -78,6 +78,10 @@ config HAVE_KPROBES
 config HAVE_KRETPROBES
 	bool
 
+# select this if the arch has the asm/seccomp.h file.
+config HAVE_SECCOMP
+	bool
+
 #
 # An arch should select this if it provides all these things:
 #
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 206cb79..b7c124e 100644  
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -4,6 +4,7 @@ config MIPS
 	select HAVE_IDE
 	select HAVE_OPROFILE
 	select HAVE_ARCH_KGDB
+	select HAVE_SECCOMP
 	# Horrible source of confusion.  Die, die, die ...
 	select EMBEDDED
 	select RTC_LIB
@@ -1949,23 +1950,6 @@ config KEXEC
 	  support.  As of this writing the exact hardware interface is
 	  strongly in flux, so no good recommendation can be made.
 
-config SECCOMP
-	bool "Enable seccomp to safely compute untrusted bytecode"
-	depends on PROC_FS
-	default y
-	help
-	  This kernel feature is useful for number crunching applications
-	  that may need to compute untrusted bytecode during their
-	  execution. By using pipes or other transports made available to
-	  the process as file descriptors supporting the read/write
-	  syscalls, it's possible to isolate those applications in
-	  their own address space using seccomp. Once seccomp is
-	  enabled via /proc/<pid>/seccomp, it cannot be disabled
-	  and the task is only allowed to execute a few safe syscalls
-	  defined by each seccomp mode.
-
-	  If unsure, say Y. Only embedded should say N here.
-
 endmenu
 
 config RWSEM_GENERIC_SPINLOCK
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 054861c..2c19cfd 100644  
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -24,7 +24,6 @@
 #include <linux/user.h>
 #include <linux/security.h>
 #include <linux/audit.h>
-#include <linux/seccomp.h>
 
 #include <asm/byteorder.h>
 #include <asm/cpu.h>
@@ -564,10 +563,6 @@ static inline int audit_arch(void)
  */
 asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
 {
-	/* do the secure computing check first */
-	if (!entryexit)
-		secure_computing(regs->regs[0]);
-
 	if (unlikely(current->audit_context) && entryexit)
 		audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]),
 		                   regs->regs[2]);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 74cc312..c71ac02 100644  
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -119,6 +119,7 @@ config PPC
 	select HAVE_ARCH_KGDB
 	select HAVE_KRETPROBES
 	select HAVE_ARCH_TRACEHOOK
+	select HAVE_SECCOMP
 	select HAVE_LMB
 	select HAVE_DMA_ATTRS if PPC64
 	select USE_GENERIC_SMP_HELPERS if SMP
@@ -531,23 +532,6 @@ config ARCH_WANTS_FREEZER_CONTROL
 source kernel/power/Kconfig
 endif
 
-config SECCOMP
-	bool "Enable seccomp to safely compute untrusted bytecode"
-	depends on PROC_FS
-	default y
-	help
-	  This kernel feature is useful for number crunching applications
-	  that may need to compute untrusted bytecode during their
-	  execution. By using pipes or other transports made available to
-	  the process as file descriptors supporting the read/write
-	  syscalls, it's possible to isolate those applications in
-	  their own address space using seccomp. Once seccomp is
-	  enabled via /proc/<pid>/seccomp, it cannot be disabled
-	  and the task is only allowed to execute a few safe syscalls
-	  defined by each seccomp mode.
-
-	  If unsure, say Y. Only embedded should say N here.
-
 endmenu
 
 config ISA_DMA_API
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index 9665a26..4d30be8 100644  
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -105,7 +105,6 @@ static inline struct thread_info *curren
 #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
 #define TIF_SINGLESTEP		8	/* singlestepping active */
 #define TIF_MEMDIE		9
-#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 */
@@ -123,14 +122,13 @@ static inline struct thread_info *curren
 #define _TIF_PERFMON_CTXSW	(1<<TIF_PERFMON_CTXSW)
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
-#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_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
 
 #define _TIF_USER_WORK_MASK	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
 				 _TIF_NOTIFY_RESUME)
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 3635be6..f5657c3 100644  
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -27,7 +27,6 @@
 #include <linux/user.h>
 #include <linux/security.h>
 #include <linux/signal.h>
-#include <linux/seccomp.h>
 #include <linux/audit.h>
 #ifdef CONFIG_PPC32
 #include <linux/module.h>
@@ -1021,8 +1020,6 @@ long do_syscall_trace_enter(struct pt_re
 {
 	long ret = 0;
 
-	secure_computing(regs->gpr[0]);
-
 	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
 	    tracehook_report_syscall_entry(regs))
 		/*
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index ebabe51..5786e77 100644  
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -14,6 +14,7 @@ config SUPERH
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_IOREMAP_PROT if MMU
 	select HAVE_ARCH_TRACEHOOK
+	select HAVE_SECCOMP
 	help
 	  The SuperH is a RISC processor targeted for use in embedded systems
 	  and consumer electronics; it was also used in the Sega Dreamcast
@@ -521,22 +522,6 @@ config CRASH_DUMP
 
 	  For more details see Documentation/kdump/kdump.txt
 
-config SECCOMP
-	bool "Enable seccomp to safely compute untrusted bytecode"
-	depends on PROC_FS
-	help
-	  This kernel feature is useful for number crunching applications
-	  that may need to compute untrusted bytecode during their
-	  execution. By using pipes or other transports made available to
-	  the process as file descriptors supporting the read/write
-	  syscalls, it's possible to isolate those applications in
-	  their own address space using seccomp. Once seccomp is
-	  enabled via prctl, it cannot be disabled and the task is only
-	  allowed to execute a few safe syscalls defined by each seccomp
-	  mode.
-
-	  If unsure, say N.
-
 config SMP
 	bool "Symmetric multi-processing support"
 	depends on SYS_SUPPORTS_SMP
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index f09ac48..e1da51a 100644  
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -114,7 +114,6 @@ extern void free_thread_info(struct thre
 #define TIF_RESTORE_SIGMASK	3	/* restore signal mask in do_signal() */
 #define TIF_SINGLESTEP		4	/* singlestepping active */
 #define TIF_SYSCALL_AUDIT	5	/* syscall auditing active */
-#define TIF_SECCOMP		6	/* secure computing */
 #define TIF_NOTIFY_RESUME	7	/* callback before returning to user */
 #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
@@ -127,7 +126,6 @@ extern void free_thread_info(struct thre
 #define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
-#define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_USEDFPU		(1 << TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
@@ -141,7 +139,7 @@ extern void free_thread_info(struct thre
 
 /* work to do in syscall trace */
 #define _TIF_WORK_SYSCALL_MASK	(_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
-				 _TIF_SYSCALL_AUDIT | _TIF_SECCOMP)
+				 _TIF_SYSCALL_AUDIT)
 
 /* work to do on any return to u-space */
 #define _TIF_ALLWORK_MASK	(_TIF_SYSCALL_TRACE | _TIF_SIGPENDING      | \
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 29ca09d..c83d0fe 100644  
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -22,7 +22,6 @@
 #include <linux/signal.h>
 #include <linux/io.h>
 #include <linux/audit.h>
-#include <linux/seccomp.h>
 #include <linux/tracehook.h>
 #include <linux/elf.h>
 #include <linux/regset.h>
@@ -438,8 +437,6 @@ asmlinkage long do_syscall_trace_enter(s
 {
 	long ret = 0;
 
-	secure_computing(regs->regs[0]);
-
 	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
 	    tracehook_report_syscall_entry(regs))
 		/*
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 6950974..e65dbe0 100644  
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -27,7 +27,6 @@
 #include <linux/signal.h>
 #include <linux/syscalls.h>
 #include <linux/audit.h>
-#include <linux/seccomp.h>
 #include <linux/tracehook.h>
 #include <linux/elf.h>
 #include <linux/regset.h>
@@ -427,8 +426,6 @@ asmlinkage long long do_syscall_trace_en
 {
 	long long ret = 0;
 
-	secure_computing(regs->regs[9]);
-
 	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
 	    tracehook_report_syscall_entry(regs))
 		/*
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 639ac80..b303b93 100644  
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -227,7 +227,7 @@ register struct thread_info *current_thr
 /* flag bit 6 is available */
 #define TIF_32BIT		7	/* 32-bit binary */
 /* flag bit 8 is available */
-#define TIF_SECCOMP		9	/* secure computing */
+/* flag bit 9 is available */
 #define TIF_SYSCALL_AUDIT	10	/* syscall auditing active */
 /* flag bit 11 is available */
 /* NOTE: Thread flags >= 12 should be ones we have no interest
@@ -246,7 +246,6 @@ register struct thread_info *current_thr
 #define _TIF_PERFCTR		(1<<TIF_PERFCTR)
 #define _TIF_UNALIGNED		(1<<TIF_UNALIGNED)
 #define _TIF_32BIT		(1<<TIF_32BIT)
-#define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bc2fbad..25ec433 100644  
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -37,6 +37,7 @@ config X86
 	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
+	select HAVE_SECCOMP
 	select HAVE_GENERIC_DMA_COHERENT if X86_32
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS
 	select USER_STACKTRACE_SUPPORT
@@ -1324,22 +1325,6 @@ config EFI
   	resultant kernel should continue to boot on existing non-EFI
   	platforms.
 
-config SECCOMP
-	def_bool y
-	prompt "Enable seccomp to safely compute untrusted bytecode"
-	help
-	  This kernel feature is useful for number crunching applications
-	  that may need to compute untrusted bytecode during their
-	  execution. By using pipes or other transports made available to
-	  the process as file descriptors supporting the read/write
-	  syscalls, it's possible to isolate those applications in
-	  their own address space using seccomp. Once seccomp is
-	  enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
-	  and the task is only allowed to execute a few safe syscalls
-	  defined by each seccomp mode.
-
-	  If unsure, say Y. Only embedded should say N here.
-
 config CC_STACKPROTECTOR
 	bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
 	depends on X86_64 && EXPERIMENTAL && BROKEN
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 4646902..21e7046 100644  
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -341,8 +341,7 @@ sysenter_past_esp:
 
 	GET_THREAD_INFO(%ebp)
 
-	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
-	testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
+	testb $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
 	jnz sysenter_audit
 sysenter_do_call:
 	cmpl $(nr_syscalls), %eax
@@ -366,7 +365,7 @@ sysenter_exit:
 
 #ifdef CONFIG_AUDITSYSCALL
 sysenter_audit:
-	testw $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
+	testb $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
 	jnz syscall_trace_entry
 	addl $4,%esp
 	CFI_ADJUST_CFA_OFFSET -4
@@ -420,8 +419,7 @@ ENTRY(system_call)
 	SAVE_ALL
 	GET_THREAD_INFO(%ebp)
 					# system call tracing in operation / emulation
-	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
-	testw $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
+	testb $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
 	jnz syscall_trace_entry
 	cmpl $(nr_syscalls), %eax
 	jae syscall_badsys
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 06ca07f..0d6bcff 100644  
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -19,7 +19,6 @@
 #include <linux/elf.h>
 #include <linux/security.h>
 #include <linux/audit.h>
-#include <linux/seccomp.h>
 #include <linux/signal.h>
 
 #include <asm/uaccess.h>
@@ -1411,9 +1410,6 @@ asmregparm long syscall_trace_enter(stru
 	if (test_thread_flag(TIF_SINGLESTEP))
 		regs->flags |= X86_EFLAGS_TF;
 
-	/* do the secure computing check first */
-	secure_computing(regs->orig_ax);
-
 	if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
 		ret = -1L;
 
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 786ef2d..4a22d98 100644  
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -76,7 +76,6 @@ struct sched_param {
 #include <linux/percpu.h>
 #include <linux/topology.h>
 #include <linux/proportions.h>
-#include <linux/seccomp.h>
 #include <linux/rcupdate.h>
 #include <linux/rtmutex.h>
 
@@ -1286,7 +1285,6 @@ struct task_struct {
 	uid_t loginuid;
 	unsigned int sessionid;
 #endif
-	seccomp_t seccomp;
 
 #ifdef CONFIG_UTRACE
 	struct utrace utrace;
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 262a8dc..02d7adb 100644  
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -4,27 +4,13 @@
 
 #ifdef CONFIG_SECCOMP
 
-#include <linux/thread_info.h>
 #include <asm/seccomp.h>
 
-typedef struct { int mode; } seccomp_t;
-
-extern void __secure_computing(int);
-static inline void secure_computing(int this_syscall)
-{
-	if (unlikely(test_thread_flag(TIF_SECCOMP)))
-		__secure_computing(this_syscall);
-}
-
 extern long prctl_get_seccomp(void);
 extern long prctl_set_seccomp(unsigned long);
 
 #else /* CONFIG_SECCOMP */
 
-typedef struct { } seccomp_t;
-
-#define secure_computing(x) do { } while (0)
-
 static inline long prctl_get_seccomp(void)
 {
 	return -EINVAL;
diff --git a/init/Kconfig b/init/Kconfig
index 4b5ab3e..bc90ad3 100644  
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1069,6 +1069,24 @@ menuconfig UTRACE
 	  kernel interface exported to kernel modules, to track events in
 	  user threads, extract and change user thread state.
 
+config SECCOMP
+	bool "Enable seccomp to safely compute untrusted bytecode"
+	default y if UTRACE
+	depends on UTRACE
+	depends on HAVE_SECCOMP
+	help
+	  This kernel feature is useful for number crunching applications
+	  that may need to compute untrusted bytecode during their
+	  execution. By using pipes or other transports made available to
+	  the process as file descriptors supporting the read/write
+	  syscalls, it's possible to isolate those applications in
+	  their own address space using seccomp. Once seccomp is
+	  enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
+	  and the task is only allowed to execute a few safe syscalls
+	  defined by each seccomp mode.
+
+	  If unsure, say Y. Only embedded should say N here.
+
 source "block/Kconfig"
 
 config PREEMPT_NOTIFIERS
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 57d4b13..627e8e7 100644  
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -1,86 +1,110 @@
-/*
- * linux/kernel/seccomp.c
- *
- * Copyright 2004-2005  Andrea Arcangeli <andrea@cpushare.com>
- *
- * This defines a simple but solid secure-computing mode.
- */
-
 #include <linux/seccomp.h>
-#include <linux/sched.h>
+#include <linux/utrace.h>
+#include <linux/signal.h>
+#include <linux/err.h>
 #include <linux/compat.h>
-
-/* #define SECCOMP_DEBUG 1 */
-#define NR_SECCOMP_MODES 1
+#include <linux/prctl.h>
+#include <asm/syscall.h>
 
 /*
- * Secure computing mode 1 allows only read/write/exit/sigreturn.
- * To be fully secure this must be combined with rlimit
- * to limit the stack allocations too.
+ * If it's an accepted syscall, run it normally.
+ * If not, send ourselves a SIGKILL and abort the syscall.
  */
-static int mode1_syscalls[] = {
-	__NR_seccomp_read, __NR_seccomp_write, __NR_seccomp_exit, __NR_seccomp_sigreturn,
-	0, /* null terminated */
-};
+static u32 secure_syscall_entry(u32 action,
+				struct utrace_engine *engine,
+				struct task_struct *task,
+				struct pt_regs *regs)
+{
+	int callno = syscall_get_nr(task, regs);
 
 #ifdef CONFIG_COMPAT
-static int mode1_syscalls_32[] = {
-	__NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32,
-	0, /* null terminated */
-};
+	if (is_compat_task())
+		switch (callno) {
+		case __NR_seccomp_read_32:
+		case __NR_seccomp_write_32:
+		case __NR_seccomp_exit_32:
+		case __NR_seccomp_sigreturn_32:
+			return UTRACE_RESUME | UTRACE_SYSCALL_RUN;
+		}
+	else
 #endif
+		switch (callno) {
+		case __NR_seccomp_read:
+		case __NR_seccomp_write:
+		case __NR_seccomp_exit:
+		case __NR_seccomp_sigreturn:
+			return UTRACE_RESUME | UTRACE_SYSCALL_RUN;
+		}
 
-void __secure_computing(int this_syscall)
+	force_sig(SIGKILL, task);
+	return UTRACE_RESUME | UTRACE_SYSCALL_ABORT;
+}
+
+static const struct utrace_engine_ops secure_syscall_ops =
 {
-	int mode = current->seccomp.mode;
-	int * syscall;
+	.report_syscall_entry = secure_syscall_entry
+};
 
-	switch (mode) {
-	case 1:
-		syscall = mode1_syscalls;
-#ifdef CONFIG_COMPAT
-		if (is_compat_task())
-			syscall = mode1_syscalls_32;
-#endif
-		do {
-			if (*syscall == this_syscall)
-				return;
-		} while (*++syscall);
-		break;
-	default:
-		BUG();
+/*
+ * Set up a utrace engine to call secure_syscall_entry() for each system call.
+ * Also act like prctl(PR_SET_TSC, PR_TSC_SIGSEGV).
+ */
+static int enable_secure_syscall(void)
+{
+	struct utrace_engine *engine;
+	int ret;
+
+	engine = utrace_attach_task(current,
+				    UTRACE_ATTACH_CREATE |
+				    UTRACE_ATTACH_EXCLUSIVE |
+				    UTRACE_ATTACH_MATCH_OPS,
+				    &secure_syscall_ops, NULL);
+	if (IS_ERR(engine)) {
+		ret = PTR_ERR(engine);
+		return ret == -EEXIST ? -EPERM : ret;
 	}
 
-#ifdef SECCOMP_DEBUG
-	dump_stack();
+	ret = utrace_set_events(current, engine, UTRACE_EVENT(SYSCALL_ENTRY));
+	WARN_ON(ret);		/* Should never happen on current.  */
+
+	/*
+	 * This is the only outside ref on the engine.
+	 * The engine dies automatically when this task gets reaped.
+	 */
+	utrace_engine_put(engine);
+
+#ifdef SET_TSC_CTL
+	if (!ret)
+		SET_TSC_CTL(PR_TSC_SIGSEGV);
 #endif
-	do_exit(SIGKILL);
+
+	return ret;
 }
 
 long prctl_get_seccomp(void)
 {
-	return current->seccomp.mode;
+	struct utrace_engine *engine = utrace_attach_task(
+		current, UTRACE_ATTACH_MATCH_OPS, &secure_syscall_ops, NULL);
+
+	if (engine == ERR_PTR(-ENOENT))
+		return 0;
+
+	if (!IS_ERR(engine)) {
+		/*
+		 * I wonder how he managed to call prctl() with it enabled.
+		 * That should be impossible.
+		 */
+		utrace_engine_put(engine);
+		return 1;
+	}
+
+	return PTR_ERR(engine);
 }
 
 long prctl_set_seccomp(unsigned long seccomp_mode)
 {
-	long ret;
-
-	/* can set it only once to be even more secure */
-	ret = -EPERM;
-	if (unlikely(current->seccomp.mode))
-		goto out;
-
-	ret = -EINVAL;
-	if (seccomp_mode && seccomp_mode <= NR_SECCOMP_MODES) {
-		current->seccomp.mode = seccomp_mode;
-		set_thread_flag(TIF_SECCOMP);
-#ifdef TIF_NOTSC
-		disable_TSC();
-#endif
-		ret = 0;
-	}
+	if (seccomp_mode != 1)
+		return -EINVAL;
 
- out:
-	return ret;
+	return enable_secure_syscall();
 }
