Index: kernel/arch/abs32le/src/userspace.c
===================================================================
--- kernel/arch/abs32le/src/userspace.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/abs32le/src/userspace.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -36,8 +36,12 @@
 #include <stdbool.h>
 #include <arch.h>
-#include <abi/proc/uarg.h>
 #include <mm/as.h>
 
-void userspace(uspace_arg_t *kernel_uarg)
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return stack_base + stack_size;
+}
+
+void userspace(uintptr_t pc, uintptr_t sp)
 {
 	/*
Index: kernel/arch/amd64/src/userspace.c
===================================================================
--- kernel/arch/amd64/src/userspace.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/amd64/src/userspace.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -39,6 +39,10 @@
 #include <stdint.h>
 #include <arch.h>
-#include <abi/proc/uarg.h>
 #include <mm/as.h>
+
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return stack_base + stack_size;
+}
 
 /** Enter userspace
@@ -47,5 +51,5 @@
  *
  */
-void userspace(uspace_arg_t *kernel_uarg)
+void userspace(uintptr_t pc, uintptr_t sp)
 {
 	uint64_t rflags = read_rflags();
@@ -60,5 +64,4 @@
 	    "pushq %[utext_des]\n"
 	    "pushq %[entry]\n"
-	    "movq %[uarg], %%rax\n"
 
 	    /* %rdi is defined to hold pcb_ptr - set it to 0 */
@@ -66,11 +69,8 @@
 	    "iretq\n"
 	    :: [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
-	      [stack_top] "r" (kernel_uarg->uspace_stack +
-	      kernel_uarg->uspace_stack_size),
+	      [stack_top] "r" (sp),
 	      [rflags] "r" (rflags),
 	      [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
-	      [entry] "r" (kernel_uarg->uspace_entry),
-	      [uarg] "r" (kernel_uarg->uspace_uarg)
-	    : "rax"
+	      [entry] "r" (pc)
 	);
 
Index: kernel/arch/arm32/src/userspace.c
===================================================================
--- kernel/arch/arm32/src/userspace.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/arm32/src/userspace.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -61,4 +61,9 @@
 } ustate_t;
 
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return stack_base + stack_size;
+}
+
 /** Change processor mode
  *
@@ -66,36 +71,13 @@
  *
  */
-void userspace(uspace_arg_t *kernel_uarg)
+void userspace(uintptr_t pc, uintptr_t sp)
 {
-	volatile ustate_t ustate;
-
-	/* set first parameter */
-	ustate.r0 = kernel_uarg->uspace_uarg;
-
-	/* %r1 is defined to hold pcb_ptr - set it to 0 */
-	ustate.r1 = 0;
+	volatile ustate_t ustate = { };
 
 	/* pass the RAS page address in %r2 */
 	ustate.r2 = (uintptr_t) ras_page;
 
-	/* clear other registers */
-	ustate.r3 = 0;
-	ustate.r4 = 0;
-	ustate.r5 = 0;
-	ustate.r6 = 0;
-	ustate.r7 = 0;
-	ustate.r8 = 0;
-	ustate.r9 = 0;
-	ustate.r10 = 0;
-	ustate.r11 = 0;
-	ustate.r12 = 0;
-	ustate.lr = 0;
-
-	/* set user stack */
-	ustate.sp = kernel_uarg->uspace_stack +
-	    kernel_uarg->uspace_stack_size;
-
-	/* set where uspace execution starts */
-	ustate.pc = kernel_uarg->uspace_entry;
+	ustate.sp = sp;
+	ustate.pc = pc;
 
 	/* status register in user mode */
Index: kernel/arch/arm64/src/arm64.c
===================================================================
--- kernel/arch/arm64/src/arm64.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/arm64/src/arm64.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -146,9 +146,14 @@
 }
 
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return stack_base + stack_size;
+}
+
 /** Change processor mode.
  *
  * @param kernel_uarg Userspace settings (entry point, stack, ...).
  */
-void userspace(uspace_arg_t *kernel_uarg)
+void userspace(uintptr_t pc, uintptr_t sp)
 {
 	/* Prepare return to EL0. */
@@ -157,9 +162,8 @@
 
 	/* Set program entry. */
-	ELR_EL1_write(kernel_uarg->uspace_entry);
+	ELR_EL1_write(pc);
 
 	/* Set user stack. */
-	SP_EL0_write(kernel_uarg->uspace_stack +
-	    kernel_uarg->uspace_stack_size);
+	SP_EL0_write(sp);
 
 	/* Clear Thread ID register. */
@@ -170,10 +174,8 @@
 	     * Reset the kernel stack to its base value.
 	     *
-	     * Clear all general-purpose registers,
-	     * except x0 that holds an argument for
-	     * the user space.
+	     * Clear all general-purpose registers.
 	     */
 	    "mov sp, %[kstack]\n"
-	    "mov x0, %[uspace_uarg]\n"
+	    "mov x0, #0\n"
 	    "mov x1, #0\n"
 	    "mov x2, #0\n"
@@ -207,6 +209,5 @@
 	    "mov x30, #0\n"
 	    "eret\n"
-	    :: [uspace_uarg] "r" (kernel_uarg->uspace_uarg),
-	      [kstack] "r" (((uint64_t) (THREAD->kstack)) +
+	    :: [kstack] "r" (((uint64_t) (THREAD->kstack)) +
 	      MEM_STACK_SIZE - SP_DELTA)
 	);
Index: kernel/arch/ia32/src/userspace.c
===================================================================
--- kernel/arch/ia32/src/userspace.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/ia32/src/userspace.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -38,8 +38,12 @@
 #include <stdint.h>
 #include <arch.h>
-#include <abi/proc/uarg.h>
 #include <mm/as.h>
 #include <arch/cpu.h>
 #include <arch/asm.h>
+
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return stack_base + stack_size;
+}
 
 /** Enter userspace
@@ -48,5 +52,5 @@
  *
  */
-void userspace(uspace_arg_t *kernel_uarg)
+void userspace(uintptr_t pc, uintptr_t sp)
 {
 	uint32_t eflags = read_eflags();
@@ -61,5 +65,4 @@
 	    "pushl %[utext_des]\n"
 	    "pushl %[entry]\n"
-	    "movl %[uarg], %%eax\n"
 
 	    /* %edi is defined to hold pcb_ptr - set it to 0 */
@@ -70,10 +73,8 @@
 	    : [eflags_mask] "i" (~EFLAGS_NT),
 	      [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
-	      [stack_top] "r" (kernel_uarg->uspace_stack +
-	      kernel_uarg->uspace_stack_size),
+	      [stack_top] "r" (sp),
 	      [eflags] "r" ((eflags & ~(EFLAGS_NT)) | EFLAGS_IF),
 	      [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
-	      [entry] "r" (kernel_uarg->uspace_entry),
-	      [uarg] "r" (kernel_uarg->uspace_uarg),
+	      [entry] "r" (pc),
 	      [vreg_des] "r" (GDT_SELECTOR(VREG_DES))
 	    : "eax");
Index: kernel/arch/ia64/src/ia64.c
===================================================================
--- kernel/arch/ia64/src/ia64.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/ia64/src/ia64.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -218,6 +218,11 @@
 }
 
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return ALIGN_DOWN(stack_base + stack_size / 2, STACK_ALIGNMENT);
+}
+
 /** Enter userspace and never return. */
-void userspace(uspace_arg_t *kernel_uarg)
+void userspace(uintptr_t pc, uintptr_t sp)
 {
 	psr_t psr;
@@ -241,14 +246,10 @@
 	 *
 	 * When calculating stack addresses, mind the stack split between the
-	 * memory stack and the RSE stack. Each occuppies
-	 * uspace_stack_size / 2 bytes.
+	 * memory stack and the RSE stack.
+	 * Memory stack occupies area under sp, while RSE stack occupies area above.
 	 */
-	switch_to_userspace(kernel_uarg->uspace_entry,
-	    kernel_uarg->uspace_stack +
-	    kernel_uarg->uspace_stack_size / 2 -
-	    ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
-	    kernel_uarg->uspace_stack +
-	    kernel_uarg->uspace_stack_size / 2,
-	    kernel_uarg->uspace_uarg, psr.value, rsc.value);
+	switch_to_userspace(pc,
+	    sp, sp + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
+	    0, psr.value, rsc.value);
 
 	while (true)
Index: kernel/arch/mips32/include/arch/asm.h
===================================================================
--- kernel/arch/mips32/include/arch/asm.h	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/mips32/include/arch/asm.h	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -81,5 +81,5 @@
 extern void cpu_halt(void) __attribute__((noreturn));
 extern void asm_delay_loop(uint32_t);
-extern void userspace_asm(uintptr_t, uintptr_t, uintptr_t);
+extern void userspace_asm(uintptr_t, uintptr_t);
 
 extern ipl_t interrupts_disable(void);
Index: kernel/arch/mips32/src/mips32.c
===================================================================
--- kernel/arch/mips32/src/mips32.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/mips32/src/mips32.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -163,14 +163,16 @@
 }
 
-void userspace(uspace_arg_t *kernel_uarg)
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return stack_base + stack_size;
+}
+
+void userspace(uintptr_t pc, uintptr_t sp)
 {
 	/* EXL = 1, UM = 1, IE = 1 */
 	cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit |
 	    cp0_status_um_bit | cp0_status_ie_enabled_bit));
-	cp0_epc_write(kernel_uarg->uspace_entry);
-	userspace_asm(kernel_uarg->uspace_stack +
-	    kernel_uarg->uspace_stack_size,
-	    kernel_uarg->uspace_uarg,
-	    kernel_uarg->uspace_entry);
+	cp0_epc_write(pc);
+	userspace_asm(sp, pc);
 
 	while (true)
Index: kernel/arch/mips32/src/start.S
===================================================================
--- kernel/arch/mips32/src/start.S	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/mips32/src/start.S	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -339,8 +339,7 @@
 FUNCTION_BEGIN(userspace_asm)
 	move $sp, $a0
-	move $v0, $a1
-	move $t9, $a2      /* set up correct entry into PIC code */
-	xor $a0, $a0, $a0  /* $a0 is defined to hold pcb_ptr */
-	                   /* set it to 0 */
+	xor $a0, $a0, $a0  /* $a0 is defined to hold pcb_ptr, set it to 0 */
+	xor $fp, $fp, $fp  // FIXME: wipe all userspace-accessible registers
+	xor $ra, $ra, $ra
 	eret
 FUNCTION_END(userspace_asm)
Index: kernel/arch/ppc32/src/ppc32.c
===================================================================
--- kernel/arch/ppc32/src/ppc32.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/ppc32/src/ppc32.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -49,5 +49,4 @@
 #include <mm/km.h>
 #include <time/clock.h>
-#include <abi/proc/uarg.h>
 #include <console/console.h>
 #include <sysinfo/sysinfo.h>
@@ -290,11 +289,12 @@
 }
 
-void userspace(uspace_arg_t *kernel_uarg)
-{
-	userspace_asm(kernel_uarg->uspace_uarg,
-	    kernel_uarg->uspace_stack +
-	    kernel_uarg->uspace_stack_size - SP_DELTA,
-	    kernel_uarg->uspace_entry);
-
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return stack_base + stack_size - SP_DELTA;
+}
+
+void userspace(uintptr_t pc, uintptr_t sp)
+{
+	userspace_asm(0, sp, pc);
 	unreachable();
 }
Index: kernel/arch/riscv64/src/userspace.c
===================================================================
--- kernel/arch/riscv64/src/userspace.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/riscv64/src/userspace.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -33,8 +33,12 @@
  */
 
-#include <abi/proc/uarg.h>
 #include <userspace.h>
 
-void userspace(uspace_arg_t *kernel_uarg)
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return stack_base + stack_size;
+}
+
+void userspace(uintptr_t pc, uintptr_t sp)
 {
 	// FIXME
Index: kernel/arch/sparc64/src/sun4u/asm.S
===================================================================
--- kernel/arch/sparc64/src/sun4u/asm.S	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/sparc64/src/sun4u/asm.S	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -83,5 +83,5 @@
  */
 FUNCTION_BEGIN(switch_to_userspace)
-	save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
+	save %o1, 0, %sp
 	flushw
 	wrpr %g0, 0, %cleanwin		! avoid information leak
Index: kernel/arch/sparc64/src/sun4u/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sun4u/sparc64.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/sparc64/src/sun4u/sparc64.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -159,13 +159,14 @@
 }
 
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return ALIGN_DOWN(stack_base + stack_size - STACK_WINDOW_SAVE_AREA_SIZE - STACK_ARG_SAVE_AREA_SIZE, 16) - STACK_BIAS;
+}
+
 /** Switch to userspace. */
-void userspace(uspace_arg_t *kernel_uarg)
+void userspace(uintptr_t pc, uintptr_t sp)
 {
 	(void) interrupts_disable();
-	switch_to_userspace(kernel_uarg->uspace_entry,
-	    kernel_uarg->uspace_stack +
-	    kernel_uarg->uspace_stack_size -
-	    (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS),
-	    kernel_uarg->uspace_uarg);
+	switch_to_userspace(pc, sp, 0);
 
 	/* Not reached */
Index: kernel/arch/sparc64/src/sun4v/asm.S
===================================================================
--- kernel/arch/sparc64/src/sun4v/asm.S	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/sparc64/src/sun4v/asm.S	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -41,5 +41,5 @@
  */
 FUNCTION_BEGIN(switch_to_userspace)
-	save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
+	save %o1, 0, %sp
 	flushw
 	wrpr %g0, 0, %cleanwin		! avoid information leak
Index: kernel/arch/sparc64/src/sun4v/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sun4v/sparc64.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/arch/sparc64/src/sun4v/sparc64.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -157,13 +157,14 @@
 }
 
+uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size)
+{
+	return ALIGN_DOWN(stack_base + stack_size - STACK_WINDOW_SAVE_AREA_SIZE - STACK_ARG_SAVE_AREA_SIZE, 16) - STACK_BIAS;
+}
+
 /** Switch to userspace. */
-void userspace(uspace_arg_t *kernel_uarg)
+void userspace(uintptr_t pc, uintptr_t sp)
 {
 	(void) interrupts_disable();
-	switch_to_userspace(kernel_uarg->uspace_entry,
-	    kernel_uarg->uspace_stack +
-	    kernel_uarg->uspace_stack_size -
-	    (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS),
-	    kernel_uarg->uspace_uarg);
+	switch_to_userspace(pc, sp, 0);
 
 	/* Not reached */
Index: kernel/generic/include/main/uinit.h
===================================================================
--- kernel/generic/include/main/uinit.h	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/generic/include/main/uinit.h	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -36,4 +36,11 @@
 #define KERN_UINIT_H_
 
+#include <stdint.h>
+
+typedef struct {
+	uintptr_t pc;
+	uintptr_t sp;
+} uinit_arg_t;
+
 extern void uinit(void *arg);
 
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/generic/include/proc/thread.h	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -45,5 +45,4 @@
 #include <arch/cpu.h>
 #include <mm/tlb.h>
-#include <abi/proc/uarg.h>
 #include <udebug/udebug.h>
 #include <abi/proc/thread.h>
Index: kernel/generic/include/userspace.h
===================================================================
--- kernel/generic/include/userspace.h	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/generic/include/userspace.h	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -39,6 +39,8 @@
 #include <typedefs.h>
 
+extern uintptr_t arch_get_initial_sp(uintptr_t stack_base, uintptr_t stack_size);
+
 /** Switch to user-space (CPU user priviledge level) */
-extern void userspace(uspace_arg_t *uarg) __attribute__((noreturn));
+extern void userspace(sysarg_t pc, sysarg_t sp) __attribute__((noreturn));
 
 #endif
Index: kernel/generic/src/main/uinit.c
===================================================================
--- kernel/generic/src/main/uinit.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/generic/src/main/uinit.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -60,17 +60,10 @@
 #endif
 
-	uspace_arg_t *uarg = arg;
-	uspace_arg_t local_uarg;
-
-	local_uarg.uspace_entry = uarg->uspace_entry;
-	local_uarg.uspace_stack = uarg->uspace_stack;
-	local_uarg.uspace_stack_size = uarg->uspace_stack_size;
-	local_uarg.uspace_uarg = uarg->uspace_uarg;
-	local_uarg.uspace_thread_function = USPACE_NULL;
-	local_uarg.uspace_thread_arg = USPACE_NULL;
-
+	uinit_arg_t *uarg = arg;
+	sysarg_t pc = uarg->pc;
+	sysarg_t sp = uarg->sp;
 	free(uarg);
 
-	userspace(&local_uarg);
+	userspace(pc, sp);
 }
 
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/generic/src/proc/program.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -53,4 +53,5 @@
 #include <syscall/copy.h>
 #include <proc/program.h>
+#include <userspace.h>
 
 /**
@@ -72,6 +73,5 @@
 errno_t program_create(as_t *as, uspace_addr_t entry_addr, char *name, program_t *prg)
 {
-	uspace_arg_t *kernel_uarg = (uspace_arg_t *)
-	    malloc(sizeof(uspace_arg_t));
+	uinit_arg_t *kernel_uarg = malloc(sizeof(uinit_arg_t));
 	if (!kernel_uarg)
 		return ENOMEM;
@@ -104,10 +104,6 @@
 	}
 
-	kernel_uarg->uspace_entry = entry_addr;
-	kernel_uarg->uspace_stack = virt;
-	kernel_uarg->uspace_stack_size = STACK_SIZE_USER;
-	kernel_uarg->uspace_thread_function = USPACE_NULL;
-	kernel_uarg->uspace_thread_arg = USPACE_NULL;
-	kernel_uarg->uspace_uarg = USPACE_NULL;
+	kernel_uarg->pc = entry_addr;
+	kernel_uarg->sp = arch_get_initial_sp(virt, STACK_SIZE_USER);
 
 	/*
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 096c0786530d26ecc60b3c63b61e396df267c704)
+++ kernel/generic/src/proc/thread.c	(revision c7ecd290f693e7f9f29a2d321c3981c90695a028)
@@ -944,8 +944,12 @@
 
 /** Process syscall to create new thread.
- *
- */
-sys_errno_t sys_thread_create(uspace_ptr_uspace_arg_t uspace_uarg, uspace_ptr_char uspace_name,
-    size_t name_len, uspace_ptr_thread_id_t uspace_thread_id)
+ * The started thread will have initial pc and sp set to the exact values passed
+ * to the syscall. The kernel will not touch any stack data below the stack
+ * pointer, but some architectures may require some space to be available
+ * for use above it. See userspace() in kernel, and <libarch/thread.h> in libc.
+ *
+ */
+sys_errno_t sys_thread_create(sysarg_t pc, sysarg_t sp,
+    uspace_ptr_char uspace_name, size_t name_len)
 {
 	if (name_len > THREAD_NAME_BUFLEN - 1)
@@ -963,60 +967,36 @@
 	 * In case of success, kernel_uarg will be freed in uinit().
 	 */
-	uspace_arg_t *kernel_uarg =
-	    (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
+	uinit_arg_t *kernel_uarg = malloc(sizeof(uinit_arg_t));
 	if (!kernel_uarg)
 		return (sys_errno_t) ENOMEM;
 
-	rc = copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t));
-	if (rc != EOK) {
-		free(kernel_uarg);
-		return (sys_errno_t) rc;
-	}
+	kernel_uarg->pc = pc;
+	kernel_uarg->sp = sp;
+
+	// TODO: fix some unnecessary inconsistencies between architectures
 
 	thread_t *thread = thread_create(uinit, kernel_uarg, TASK,
 	    THREAD_FLAG_USPACE | THREAD_FLAG_NOATTACH, namebuf);
-	if (thread) {
-		if (uspace_thread_id) {
-			rc = copy_to_uspace(uspace_thread_id, &thread->tid,
-			    sizeof(thread->tid));
-			if (rc != EOK) {
-				/*
-				 * We have encountered a failure, but the thread
-				 * has already been created. We need to undo its
-				 * creation now.
-				 */
-
-				/*
-				 * The new thread structure is initialized, but
-				 * is still not visible to the system.
-				 * We can safely deallocate it.
-				 */
-				slab_free(thread_cache, thread);
-				free(kernel_uarg);
-
-				return (sys_errno_t) rc;
-			}
-		}
+	if (!thread) {
+		free(kernel_uarg);
+		return (sys_errno_t) ENOMEM;
+	}
 
 #ifdef CONFIG_UDEBUG
-		/*
-		 * Generate udebug THREAD_B event and attach the thread.
-		 * This must be done atomically (with the debug locks held),
-		 * otherwise we would either miss some thread or receive
-		 * THREAD_B events for threads that already existed
-		 * and could be detected with THREAD_READ before.
-		 */
-		udebug_thread_b_event_attach(thread, TASK);
+	/*
+	 * Generate udebug THREAD_B event and attach the thread.
+	 * This must be done atomically (with the debug locks held),
+	 * otherwise we would either miss some thread or receive
+	 * THREAD_B events for threads that already existed
+	 * and could be detected with THREAD_READ before.
+	 */
+	udebug_thread_b_event_attach(thread, TASK);
 #else
-		thread_attach(thread, TASK);
+	thread_attach(thread, TASK);
 #endif
-		thread_start(thread);
-		thread_put(thread);
-
-		return 0;
-	} else
-		free(kernel_uarg);
-
-	return (sys_errno_t) ENOMEM;
+	thread_start(thread);
+	thread_put(thread);
+
+	return (sys_errno_t) EOK;
 }
 
