Index: uspace/lib/c/generic/thread/fibril.c
===================================================================
--- uspace/lib/c/generic/thread/fibril.c	(revision d5409daa794d9384555eb540e3baaaa8b6a8600c)
+++ uspace/lib/c/generic/thread/fibril.c	(revision d05c2377b4a3f7c8e4909dd03fadff4954375186)
@@ -781,7 +781,8 @@
 }
 
-static void _runner_fn(void *arg)
+static errno_t _runner_fn(void *arg)
 {
 	_helper_fibril_fn(arg);
+	return EOK;
 }
 
@@ -808,9 +809,7 @@
 
 	for (int i = 0; i < n; i++) {
-		thread_id_t tid;
-		rc = thread_create(_runner_fn, NULL, "fibril runner", &tid);
+		rc = thread_create(_runner_fn, NULL, "fibril runner");
 		if (rc != EOK)
 			return i;
-		thread_detach(tid);
 	}
 
Index: uspace/lib/c/generic/thread/thread.c
===================================================================
--- uspace/lib/c/generic/thread/thread.c	(revision d5409daa794d9384555eb540e3baaaa8b6a8600c)
+++ uspace/lib/c/generic/thread/thread.c	(revision d05c2377b4a3f7c8e4909dd03fadff4954375186)
@@ -37,5 +37,4 @@
 #include <stdlib.h>
 #include <libarch/faddr.h>
-#include <abi/proc/uarg.h>
 #include <fibril.h>
 #include <stack.h>
@@ -54,17 +53,17 @@
  * and exit when thread returns back.
  *
- * @param uarg Pointer to userspace argument structure.
+ * @param arg Fibril pointer.
  *
  */
-void __thread_main(uspace_arg_t *uarg)
+static void __thread_main(void *arg)
 {
+	fibril_t *fibril = arg;
+
 	assert(!__tcb_is_set());
-
-	fibril_t *fibril = uarg->uspace_thread_arg;
 	assert(fibril);
 
 	__tcb_set(fibril->tcb);
 
-	uarg->uspace_thread_function(fibril->arg);
+	fibril->func(fibril->arg);
 	/*
 	 * XXX: we cannot free the userspace stack while running on it
@@ -90,16 +89,12 @@
  * @return Zero on success or a code from @ref errno.h on failure.
  */
-errno_t thread_create(void (*function)(void *), void *arg, const char *name,
-    thread_id_t *tid)
+errno_t thread_create(errno_t (*func)(void *), void *arg, const char *name)
 {
-	uspace_arg_t *uarg = calloc(1, sizeof(uspace_arg_t));
-	if (!uarg)
+	fibril_t *fibril = fibril_alloc();
+	if (!fibril)
 		return ENOMEM;
 
-	fibril_t *fibril = fibril_alloc();
-	if (!fibril) {
-		free(uarg);
-		return ENOMEM;
-	}
+	fibril->func = func;
+	fibril->arg = arg;
 
 	size_t stack_size = stack_size_get();
@@ -109,18 +104,13 @@
 	if (stack == AS_MAP_FAILED) {
 		fibril_teardown(fibril);
-		free(uarg);
 		return ENOMEM;
 	}
 
-	fibril->arg = arg;
-	uarg->uspace_entry = (void *) FADDR(__thread_entry);
-	uarg->uspace_stack = stack;
-	uarg->uspace_stack_size = stack_size;
-	uarg->uspace_thread_function = function;
-	uarg->uspace_thread_arg = fibril;
-	uarg->uspace_uarg = uarg;
+	uintptr_t sp = arch_thread_prepare(stack, stack_size, __thread_main,
+	    fibril);
 
-	errno_t rc = (errno_t) __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg,
-	    (sysarg_t) name, (sysarg_t) str_size(name), (sysarg_t) tid);
+	errno_t rc = (errno_t) __SYSCALL4(SYS_THREAD_CREATE,
+	    (sysarg_t) FADDR(__thread_entry), sp,
+	    (sysarg_t) name, (sysarg_t) str_size(name));
 
 	if (rc != EOK) {
@@ -130,5 +120,4 @@
 		 */
 		as_area_destroy(stack);
-		free(uarg);
 	}
 
@@ -148,14 +137,4 @@
 	while (true)
 		;
-}
-
-/** Detach thread.
- *
- * Currently not implemented.
- *
- * @param thread TID.
- */
-void thread_detach(thread_id_t thread)
-{
 }
 
