diff --git a/bsd-user/arm/target_vmparam.h b/bsd-user/arm/target_vmparam.h
index 0427244..24dca00 100644
--- a/bsd-user/arm/target_vmparam.h
+++ b/bsd-user/arm/target_vmparam.h
@@ -20,6 +20,10 @@ struct target_ps_strings {
 
 #define TARGET_SZSIGCODE 0
 
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+    MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
 #else
 
 #define TARGET_USRSTACK			0
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 0c48f5a..f5f652f 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -715,9 +715,13 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
     /* Create enough stack to hold everything.  If we don't use
      * it for args, we'll use it for something else...
      */
+#ifdef TARGET_STACK_SIZE
+    size = TARGET_STACK_SIZE;
+#else
     size = x86_stack_size;
     if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
         size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
+#endif
 
 #ifdef TARGET_USRSTACK
     stack_base = TARGET_USRSTACK - size;
@@ -738,7 +742,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
 
 #if defined(__FreeBSD__)
     /*
-     * The inital FreeBSD stack looks like follows:
+     * The inital FreeBSD stack is as follows:
      * (see kern/kern_exec.c exec_copyout_strings() )
      *
      *  Hi Address -> char **ps_argvstr  (struct ps_strings for ps, w, etc.)
diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list
index bcdd931..c66dcfa 100644
--- a/bsd-user/freebsd/strace.list
+++ b/bsd-user/freebsd/strace.list
@@ -118,6 +118,7 @@
 { TARGET_FREEBSD_NR_revoke, "revoke", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_rfork, "rfork", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_rtprio_thread, "rtprio_thread", "%s(%d, %d, %p)", NULL, NULL },
 { TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL },
diff --git a/bsd-user/i386/target_vmparam.h b/bsd-user/i386/target_vmparam.h
index 8fc98d5..ea7546c 100644
--- a/bsd-user/i386/target_vmparam.h
+++ b/bsd-user/i386/target_vmparam.h
@@ -19,6 +19,10 @@ struct target_ps_strings {
 
 #define TARGET_SZSIGCODE 0
 
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+    MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
 #else
 
 #define	TARGET_USRSTACK	 0
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 7cc77aa..32bd3e5 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -855,7 +855,9 @@ void cpu_loop(CPUARMState *env)
                 goto do_segv;
             }
             break;
+#if 0
         error:
+#endif
         default:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                     trapnr);
diff --git a/bsd-user/mips/target_vmparam.h b/bsd-user/mips/target_vmparam.h
index 9fca7f3..8abc26c 100644
--- a/bsd-user/mips/target_vmparam.h
+++ b/bsd-user/mips/target_vmparam.h
@@ -21,6 +21,10 @@ struct target_ps_strings {
 
 #define TARGET_SZSIGCODE 0
 
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+    MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
 #else
 
 #define	TARGET_USRSTACK 0
diff --git a/bsd-user/mips64/target_vmparam.h b/bsd-user/mips64/target_vmparam.h
index 47c2267..55ed254 100644
--- a/bsd-user/mips64/target_vmparam.h
+++ b/bsd-user/mips64/target_vmparam.h
@@ -20,6 +20,10 @@ struct target_ps_strings {
 
 #define TARGET_PS_STRINGS  (TARGET_USRSTACK - sizeof(struct target_ps_strings))
 
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+    MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
 #else
 
 #define	TARGET_USRSTACK	 0
diff --git a/bsd-user/sparc/target_vmparam.h b/bsd-user/sparc/target_vmparam.h
index 9494c46..82c29ed 100644
--- a/bsd-user/sparc/target_vmparam.h
+++ b/bsd-user/sparc/target_vmparam.h
@@ -1,8 +1,6 @@
 #ifndef _TARGET_VMPARAM_H_
 #define _TARGET_VMPARAM_H_
 
-#define	TARGET_USRSTACK 0
-
 #ifdef __FreeBSD__
 struct target_ps_strings {
         abi_ulong ps_argvstr;
@@ -14,9 +12,22 @@ struct target_ps_strings {
 #define TARGET_SPACE_USRSPACE   4096
 #define TARGET_ARG_MAX          262144
 
+/* XXX  */
+#define TARGET_VM_MAXUSER_ADDRESS	(0xc0000000 - (512 * 1024 * 1024))
+#define TARGET_USRSTACK			TARGET_VM_MAXUSER_ADDRESS
+
 #define TARGET_PS_STRINGS  (TARGET_USRSTACK - sizeof(struct target_ps_strings))
 
 #define TARGET_SZSIGCODE 0
+
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+    MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
+#else
+
+#define	TARGET_USRSTACK 0
+
 #endif /* __FreeBSD__ */
 
 #endif /* _TARGET_VMPARAM_H_ */
diff --git a/bsd-user/sparc64/target_vmparam.h b/bsd-user/sparc64/target_vmparam.h
index 12af063..7f2b464 100644
--- a/bsd-user/sparc64/target_vmparam.h
+++ b/bsd-user/sparc64/target_vmparam.h
@@ -21,6 +21,10 @@ struct target_ps_strings {
 
 #define TARGET_SZSIGCODE 0
 
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+    MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
 #else
 
 #define	TARGET_USRSTACK 0
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index a40d7ce..8565ae8 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -409,19 +409,44 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol
     for (p = hnamep, q = snamep, i = 0; i < namelen; p++, i++)
        *q++ = tswap32(*p);
     oidfmt(snamep, namelen, NULL, &kind);
-    /* XXX swap hnewp */
-#if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32
-    /* XXX there may be more sysctls that differ */
-    if (namelen == 2 &&
-        snamep[0] == CTL_KERN && snamep[1] == KERN_USRSTACK &&
-        holdlen && holdlen == 4 && hnewp == NULL) {
-       (*(uint32_t *)holdp) = 0xfffff000U;
-       ret = 0;
-    } else
+
+    /* Handle some arch/emulator dependent sysctl()'s here. */
+    if (CTL_KERN == snamep[0]) {
+	    switch(snamep[1]) {
+	    case KERN_USRSTACK:
+#if defined(TARGET_ARM) && HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32
+		    (*(uint32_t *)holdp) = 0xfffff000U;
+		    holdlen = sizeof(uint32_t);
+		    ret = 0;
+#elif TARGET_USRSTACK != 0
+		    (*(abi_ulong *)holdp) = tswapal(TARGET_USRSTACK);
+		    holdlen = sizeof(abi_ulong);
+		    ret = 0;
+#else
+		    ret = -TARGET_ENOENT;
+#endif
+		    goto out;
+
+	    case KERN_PS_STRINGS:
+#if defined(TARGET_PS_STRINGS)
+		    (*(abi_ulong *)holdp) = tswapal(TARGET_PS_STRINGS);
+		    holdlen = sizeof(abi_ulong);
+		    ret = 0;
+#else
+		    ret = -TARGET_ENOENT;
 #endif
+		    goto out;
+
+	    default:
+		    break;
+	    }
+    }
+
     ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen));
     if (!ret)
         sysctl_oldcvt(holdp, holdlen, kind);
+
+out:
     put_user_ual(holdlen, oldlenp);
     unlock_user(hnamep, namep, 0);
     unlock_user(holdp, oldp, holdlen);
@@ -3293,6 +3318,47 @@ host_to_target_fhandle(abi_ulong target_addr, fhandle_t *host_fh)
 }
 
 static inline abi_long
+target_to_host_rtprio(struct rtprio *host_rtp, abi_ulong target_addr)
+{
+	struct target_rtprio *target_rtp;
+
+	if (!lock_user_struct(VERIFY_READ, target_rtp, target_addr, 1))
+		return (-TARGET_EFAULT);
+	__get_user(host_rtp->type, &target_rtp->type);
+	__get_user(host_rtp->prio, &target_rtp->prio);
+	unlock_user_struct(target_rtp, target_addr, 0);
+	return (0);
+}
+
+static inline abi_long
+host_to_target_rtprio(abi_ulong target_addr, struct rtprio *host_rtp)
+{
+	struct target_rtprio *target_rtp;
+
+	if (!lock_user_struct(VERIFY_WRITE, target_rtp, target_addr, 0))
+		return (-TARGET_EFAULT);
+	__put_user(host_rtp->type, &target_rtp->type);
+	__put_user(host_rtp->prio, &target_rtp->prio);
+	unlock_user_struct(target_rtp, target_addr, 1);
+	return (0);
+}
+
+static inline abi_long
+do_rtprio_thread(int function, lwpid_t lwpid, abi_ulong target_addr)
+{
+	int ret;
+	struct rtprio rtp;
+
+	ret = target_to_host_rtprio(&rtp, target_addr);
+	if (0 == ret)
+		ret = get_errno(rtprio_thread(function, lwpid, &rtp));
+	if (0 == ret)
+		ret = host_to_target_rtprio(target_addr, &rtp);
+
+	return (ret);
+}
+
+static inline abi_long
 target_to_host_sched_param(struct sched_param *host_sp, abi_ulong target_addr)
 {
 	struct target_sched_param *target_sp;
@@ -4617,12 +4683,17 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
 		struct target_rlimit *target_rlim;
 		struct rlimit rlim;
 
-		if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
-			goto efault;
-		rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
-		rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
-		unlock_user_struct(target_rlim, arg2, 0);
-		ret = get_errno(setrlimit(resource, &rlim));
+		if (RLIMIT_STACK == resource) {
+			/* XXX We should, maybe, allow the stack size to shrink */
+			ret = -TARGET_EPERM;
+		} else {
+			if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
+				goto efault;
+			rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
+			rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
+			unlock_user_struct(target_rlim, arg2, 0);
+			ret = get_errno(setrlimit(resource, &rlim));
+		}
 	}
 	break;
 
@@ -4633,7 +4704,12 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
 		struct target_rlimit *target_rlim;
 		struct rlimit rlim;
 
-		ret = get_errno(getrlimit(resource, &rlim));
+		/* Return the target stack size */
+		if (RLIMIT_STACK == resource) {
+			rlim.rlim_cur = rlim.rlim_max = TARGET_STACK_SIZE;
+			ret = 0;
+		} else
+			ret = get_errno(getrlimit(resource, &rlim));
 		if (!is_error(ret)) {
 			if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2,
 				0))
@@ -6148,7 +6224,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
 	 break;
 
     case TARGET_FREEBSD_NR_rtprio_thread:
-	 ret = 0;
+	 ret = do_rtprio_thread(arg1, arg2, arg3);
 	 break;
 
     case TARGET_FREEBSD_NR_getcontext:
diff --git a/bsd-user/x86_64/target_vmparam.h b/bsd-user/x86_64/target_vmparam.h
index aa5e0e0..ff9f534 100644
--- a/bsd-user/x86_64/target_vmparam.h
+++ b/bsd-user/x86_64/target_vmparam.h
@@ -20,6 +20,10 @@ struct target_ps_strings {
 
 #define TARGET_SZSIGCODE 0
 
+/* Make stack size large enough to hold everything. */
+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
+    MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+
 #else
 
 #define	TARGET_USRSTACK	 0