Index: kern/kern_exec.c
===================================================================
--- kern/kern_exec.c	(revision 185571)
+++ kern/kern_exec.c	(working copy)
@@ -108,6 +108,9 @@
     struct mac *mac_p);
 static void exec_free_args(struct image_args *);
 
+struct sx execve_lock;
+SX_SYSINIT(execve_lock, &execve_lock, "execve lock");
+
 /* XXX This should be vm_size_t. */
 SYSCTL_PROC(_kern, KERN_PS_STRINGS, ps_strings, CTLTYPE_ULONG|CTLFLAG_RD,
     NULL, 0, sysctl_kern_ps_strings, "LU", "");
@@ -275,6 +278,7 @@
 	struct proc *p = td->td_proc;
 	int error;
 
+	sx_slock(&execve_lock);
 	AUDIT_ARG(argv, args->begin_argv, args->argc,
 	    args->begin_envv - args->begin_argv);
 	AUDIT_ARG(envv, args->begin_envv, args->envc,
@@ -284,6 +288,7 @@
 		if (thread_single(SINGLE_BOUNDARY)) {
 			PROC_UNLOCK(p);
 	       		exec_free_args(args);
+			sx_sunlock(&execve_lock);
 			return (ERESTART);	/* Try again later. */
 		}
 		PROC_UNLOCK(p);
@@ -304,6 +309,7 @@
 		PROC_UNLOCK(p);
 	}
 
+	sx_sunlock(&execve_lock);
 	return (error);
 }
 
Index: compat/linux/linux_emul.c
===================================================================
--- compat/linux/linux_emul.c	(revision 185571)
+++ compat/linux/linux_emul.c	(working copy)
@@ -57,6 +57,7 @@
 
 struct sx	emul_shared_lock;
 struct mtx	emul_lock;
+uint32_t	linux_procs_count = 0;		/* counts Linux processes */
 
 /* this returns locked reference to the emuldata entry (if found) */
 struct linux_emuldata *
@@ -202,6 +203,7 @@
 		error = copyout(&null, child_clear_tid, sizeof(null));
 		if (error) {
 			free(em, M_LINUX);
+			atomic_subtract_32(&linux_procs_count, 1);
 			return;
 		}
 
@@ -223,6 +225,7 @@
 
 	/* clean the stuff up */
 	free(em, M_LINUX);
+	atomic_subtract_32(&linux_procs_count, 1);
 
 	/* this is a little weird but rewritten from exit1() */
 	sx_xlock(&proctree_lock);
@@ -254,8 +257,10 @@
 linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
 {
 	if (__predict_false(imgp->sysent == &elf_linux_sysvec
-	    && p->p_sysent != &elf_linux_sysvec))
+	    && p->p_sysent != &elf_linux_sysvec)) {
+		atomic_add_32(&linux_procs_count, 1);
 		linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0);
+	}
 	if (__predict_false(imgp->sysent != &elf_linux_sysvec
 	    && p->p_sysent == &elf_linux_sysvec)) {
 		struct linux_emuldata *em;
@@ -285,6 +290,7 @@
 			EMUL_SHARED_WUNLOCK(&emul_shared_lock);
 
 		free(em, M_LINUX);
+     		atomic_subtract_32(&linux_procs_count, 1);
 	}
 }
 
Index: compat/linux/linux_mib.c
===================================================================
--- compat/linux/linux_mib.c	(revision 185571)
+++ compat/linux/linux_mib.c	(working copy)
@@ -38,6 +38,7 @@
 #include <sys/jail.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/sx.h>
 
 #include "opt_compat.h"
 
@@ -48,6 +49,9 @@
 #endif
 #include <compat/linux/linux_mib.h>
 
+extern uint32_t linux_procs_count;
+extern struct sx execve_lock;
+
 struct linux_prison {
 	char	pr_osname[LINUX_MAX_UTSNAME];
 	char	pr_osrelease[LINUX_MAX_UTSNAME];
@@ -95,7 +99,13 @@
 	error = sysctl_handle_string(oidp, osrelease, LINUX_MAX_UTSNAME, req);
 	if (error || req->newptr == NULL)
 		return (error);
+
+	sx_xlock(&execve_lock);
+	if (!atomic_cmpset_32(&linux_procs_count, 0, 0))
+		return (EBUSY);
+
 	error = linux_set_osrelease(req->td, osrelease);
+	sx_xunlock(&execve_lock);
 	return (error);
 }
 
Index: i386/linux/linux_machdep.c
===================================================================
--- i386/linux/linux_machdep.c	(revision 185571)
+++ i386/linux/linux_machdep.c	(working copy)
@@ -72,6 +72,7 @@
 #include "opt_posix.h"
 
 extern struct sysentvec elf32_freebsd_sysvec;	/* defined in i386/i386/elf_machdep.c */
+extern uint32_t	linux_procs_count;
 
 struct l_descriptor {
 	l_uint		entry_number;
@@ -134,9 +135,11 @@
 	error = exec_copyin_args(&eargs, newpath, UIO_SYSSPACE,
 	    args->argp, args->envp);
 	free(newpath, M_TEMP);
-	if (error == 0)
+	if (error == 0) {
+		atomic_add_32(&linux_procs_count, 1);       
 		error = kern_execve(td, &eargs, NULL);
-	if (error == 0)
+	}
+	if (error == 0) {
 	   	/* linux process can exec fbsd one, dont attempt
 		 * to create emuldata for such process using
 		 * linux_proc_init, this leads to a panic on KASSERT
@@ -144,6 +147,10 @@
 		 */
 	   	if (td->td_proc->p_sysent == &elf_linux_sysvec)
    		   	error = linux_proc_init(td, 0, 0);
+		else
+			atomic_subtract_32(&linux_procs_count, 1);
+	} 
+
 	return (error);
 }
 
@@ -305,9 +312,12 @@
 	if (ldebug(fork))
 		printf(ARGS(fork, ""));
 #endif
-
-	if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2)) != 0)
+	
+	atomic_add_32(&linux_procs_count, 1);       
+	if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2)) != 0) {
+		atomic_subtract_32(&linux_procs_count, 1);
 		return (error);
+	}
 	
 	if (error == 0) {
 		td->td_retval[0] = p2->p_pid;
@@ -345,9 +355,12 @@
 		printf(ARGS(vfork, ""));
 #endif
 
+	atomic_add_32(&linux_procs_count, 1);       
 	/* exclude RFPPWAIT */
-	if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFSTOPPED, 0, &p2)) != 0)
+	if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFSTOPPED, 0, &p2)) != 0) {
+		atomic_subtract_32(&linux_procs_count, 1);
 		return (error);
+	}
 	if (error == 0) {
 		td->td_retval[0] = p2->p_pid;
 		td->td_retval[1] = 0;
@@ -440,9 +453,12 @@
 		if (args->parent_tidptr == NULL)
 			return (EINVAL);
 
+	atomic_add_32(&linux_procs_count, 1);       
 	error = fork1(td, ff, 0, &p2);
-	if (error)
+	if (error) {
+		atomic_subtract_32(&linux_procs_count, 1);
 		return (error);
+	}
 
 	if (args->flags & (LINUX_CLONE_PARENT | LINUX_CLONE_THREAD)) {
 	   	sx_xlock(&proctree_lock);
Index: i386/linux/linux_sysvec.c
===================================================================
--- i386/linux/linux_sysvec.c	(revision 185571)
+++ i386/linux/linux_sysvec.c	(working copy)
@@ -110,6 +110,8 @@
 
 extern LIST_HEAD(futex_list, futex) futex_list;
 extern struct sx futex_sx;
+extern uint32_t linux_procs_count;
+extern struct sx execve_lock;
 
 static eventhandler_tag linux_exit_tag;
 static eventhandler_tag linux_schedtail_tag;
@@ -937,10 +939,9 @@
 			printf("cannot insert Linux ELF brand handler\n");
 		break;
 	case MOD_UNLOAD:
-		for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
-		     ++brandinfo)
-			if (elf32_brand_inuse(*brandinfo))
-				error = EBUSY;
+		sx_xlock(&execve_lock);
+		if (!atomic_cmpset_32(&linux_procs_count, 0, 0))
+			error = EBUSY;
 		if (error == 0) {
 			for (brandinfo = &linux_brandlist[0];
 			     *brandinfo != NULL; ++brandinfo)
@@ -962,6 +963,7 @@
 				printf("Linux ELF exec handler removed\n");
 		} else
 			printf("Could not deinstall ELF interpreter entry\n");
+		sx_xunlock(&execve_lock);
 		break;
 	default:
 		return EOPNOTSUPP;
Index: amd64/linux32/linux32_sysvec.c
===================================================================
--- amd64/linux32/linux32_sysvec.c	(revision 185571)
+++ amd64/linux32/linux32_sysvec.c	(working copy)
@@ -126,6 +126,8 @@
 
 extern LIST_HEAD(futex_list, futex) futex_list;
 extern struct sx futex_sx;
+extern uint32_t linux_procs_count;
+extern struct sx execve_lock;
 
 static eventhandler_tag linux_exit_tag;
 static eventhandler_tag linux_schedtail_tag;
@@ -1094,10 +1096,9 @@
 			printf("cannot insert Linux ELF brand handler\n");
 		break;
 	case MOD_UNLOAD:
-		for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
-		     ++brandinfo)
-			if (elf32_brand_inuse(*brandinfo))
-				error = EBUSY;
+		sx_xlock(&execve_lock);
+		if (!atomic_cmpset_32(&linux_procs_count, 0, 0))
+			error = EBUSY;
 		if (error == 0) {
 			for (brandinfo = &linux_brandlist[0];
 			     *brandinfo != NULL; ++brandinfo)
@@ -1119,6 +1120,7 @@
 				printf("Linux ELF exec handler removed\n");
 		} else
 			printf("Could not deinstall ELF interpreter entry\n");
+		sx_xunlock(&execve_lock);
 		break;
 	default:
 		return EOPNOTSUPP;
Index: amd64/linux32/linux32_machdep.c
===================================================================
--- amd64/linux32/linux32_machdep.c	(revision 185571)
+++ amd64/linux32/linux32_machdep.c	(working copy)
@@ -71,6 +71,8 @@
 #include <compat/linux/linux_util.h>
 #include <compat/linux/linux_emul.h>
 
+extern uint32_t linux_procs_count;
+
 struct l_old_select_argv {
 	l_int		nfds;
 	l_uintptr_t	readfds;
@@ -219,9 +221,11 @@
 	error = linux_exec_copyin_args(&eargs, path, UIO_SYSSPACE, args->argp,
 	    args->envp);
 	free(path, M_TEMP);
-	if (error == 0)
+	if (error == 0) {
+		atomic_add_32(&linux_procs_count, 1);
 		error = kern_execve(td, &eargs, NULL);
-	if (error == 0)
+	}
+	if (error == 0) {
 		/* Linux process can execute FreeBSD one, do not attempt
 		 * to create emuldata for such process using
 		 * linux_proc_init, this leads to a panic on KASSERT
@@ -229,6 +233,10 @@
 		 */
 	   	if (td->td_proc->p_sysent == &elf_linux_sysvec)
 			error = linux_proc_init(td, 0, 0);
+		else
+			atomic_subtract_32(&linux_procs_count, 1);
+	}
+
 	return (error);
 }
 
@@ -490,8 +498,11 @@
 		printf(ARGS(fork, ""));
 #endif
 
-	if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2)) != 0)
+	atomic_add_32(&linux_procs_count, 1);
+	if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2)) != 0) {
+		atomic_subtract_32(&linux_procs_count, 1);
 		return (error);
+	}
 
 	if (error == 0) {
 		td->td_retval[0] = p2->p_pid;
@@ -529,9 +540,12 @@
 		printf(ARGS(vfork, ""));
 #endif
 
+	atomic_add_32(&linux_procs_count, 1);
 	/* Exclude RFPPWAIT */
-	if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFSTOPPED, 0, &p2)) != 0)
+	if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFSTOPPED, 0, &p2)) != 0) {
+		atomic_subtract_32(&linux_procs_count, 1);
 		return (error);
+	}
 	if (error == 0) {
 	   	td->td_retval[0] = p2->p_pid;
 		td->td_retval[1] = 0;
@@ -624,9 +638,12 @@
 		if (args->parent_tidptr == NULL)
 			return (EINVAL);
 
+	atomic_add_32(&linux_procs_count, 1);       
 	error = fork1(td, ff, 0, &p2);
-	if (error)
+	if (error) {
+		atomic_subtract_32(&linux_procs_count, 1);
 		return (error);
+	}
 
 	if (args->flags & (LINUX_CLONE_PARENT | LINUX_CLONE_THREAD)) {
 	   	sx_xlock(&proctree_lock);
