Index: arch/amd64/src/userspace.c
===================================================================
--- arch/amd64/src/userspace.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ arch/amd64/src/userspace.c	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -31,5 +31,5 @@
 #include <arch/types.h>
 #include <arch.h>
-#include <proc/thread.h>
+#include <proc/uarg.h>
 #include <mm/as.h>
 
@@ -40,5 +40,5 @@
  *
  */
-void userspace(uspace_arg_t *uarg)
+void userspace(uspace_arg_t *kernel_uarg)
 {
 	ipl_t ipl;
@@ -52,13 +52,18 @@
 			  "pushq %3\n"
 			  "pushq %4\n"
+			  "movq %5, %%rax\n"
 			  "iretq\n"
 			  : : 
 			  "i" (gdtselector(UDATA_DES) | PL_USER), 
-			  "r" (uarg->uspace_stack+THREAD_STACK_SIZE), 
+			  "r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE), 
 			  "r" (ipl), 
 			  "i" (gdtselector(UTEXT_DES) | PL_USER), 
-			  "r" (uarg->uspace_entry));
+			  "r" (kernel_uarg->uspace_entry),
+			  "r" (kernel_uarg->uspace_uarg)
+			  : "rax"
+			  );
 	
 	/* Unreachable */
-	for(;;);
+	for(;;)
+		;
 }
Index: arch/ia32/src/userspace.c
===================================================================
--- arch/ia32/src/userspace.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ arch/ia32/src/userspace.c	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -31,5 +31,5 @@
 #include <arch/types.h>
 #include <arch.h>
-#include <proc/thread.h>
+#include <proc/uarg.h>
 #include <mm/as.h>
 
@@ -40,5 +40,5 @@
  *
  */
-void userspace(uspace_arg_t *uarg)
+void userspace(uspace_arg_t *kernel_uarg)
 {
 	ipl_t ipl;
@@ -47,8 +47,10 @@
 
 	__asm__ volatile (
-		/* CLNT */
+		/*
+		 * Clear nested task flag.
+		 */
 		"pushfl\n"
 		"pop %%eax\n"
-		"and $0xffffbfff,%%eax\n"
+		"and $0xffffbfff, %%eax\n"
 		"push %%eax\n"
 		"popfl\n"
@@ -59,8 +61,10 @@
 		"pushl %3\n"
 		"pushl %4\n"
+		"movl %5, %%eax\n"
 		"iret"
 		: 
-		: "i" (selector(UDATA_DES) | PL_USER), "r" (uarg->uspace_stack+THREAD_STACK_SIZE),
-		  "r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (uarg->uspace_entry)
+		: "i" (selector(UDATA_DES) | PL_USER), "r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE),
+		  "r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (kernel_uarg->uspace_entry),
+		  "r" (kernel_uarg->uspace_uarg)
 		: "eax");
 	
Index: arch/ia64/include/asm.h
===================================================================
--- arch/ia64/include/asm.h	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ arch/ia64/include/asm.h	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -259,5 +259,5 @@
 extern void asm_delay_loop(__u32 t);
 
-extern void switch_to_userspace(__address entry, __address sp, __address bsp, __u64 ipsr, __u64 rsc);
+extern void switch_to_userspace(__address entry, __address sp, __address bsp, __address uspace_uarg, __u64 ipsr, __u64 rsc);
 
 #endif
Index: arch/ia64/include/faddr.h
===================================================================
--- arch/ia64/include/faddr.h	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ arch/ia64/include/faddr.h	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -32,6 +32,4 @@
 #include <arch/types.h>
 
-static __address FADDR(void (* fptr)(void));
-
 /** 
  *
@@ -42,15 +40,6 @@
  *
  */
-inline __address FADDR(void (* fptr)(void)) {
+static inline __address FADDR(void (* fptr)()) {
 	__address faddr;
-
-	/*Deprecated assembler version*/
-	/*	
-	__asm__(
-		"ld8 %0 = [%1]\n\t"
-		: "=r" (faddr)
-		: "r" (fptr)
-	);
-	*/
 
 	faddr = *((__address *)(fptr));;
Index: arch/ia64/src/asm.S
===================================================================
--- arch/ia64/src/asm.S	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ arch/ia64/src/asm.S	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -55,15 +55,16 @@
  * @param in1 Userspace stack pointer address.
  * @param in2 Userspace register stack pointer address.
- * @param in3 Value to be stored in IPSR.
- * @param in4 Value to be stored in RSC.
+ * @param in3 Userspace address of thread uspace_arg_t structure.
+ * @param in4 Value to be stored in IPSR.
+ * @param in5 Value to be stored in RSC.
  */
 .global switch_to_userspace
 switch_to_userspace:
-	alloc loc0 = ar.pfs, 5, 3, 0, 0
+	alloc loc0 = ar.pfs, 6, 3, 0, 0
 	rsm (PSR_IC_MASK | PSR_I_MASK)		/* disable interruption collection and interrupts */
 	srlz.d ;;
 	srlz.i ;;
 	
-	mov cr.ipsr = in3
+	mov cr.ipsr = in4
 	mov cr.iip = in0
 	mov r12 = in1
@@ -85,5 +86,7 @@
 	
 	mov ar.bspstore = in2 ;;
-	mov ar.rsc = in4 ;;
+	mov ar.rsc = in5 ;;
+	
+	mov r8 = in3
 	
 	rfi ;;
Index: arch/ia64/src/ia64.c
===================================================================
--- arch/ia64/src/ia64.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ arch/ia64/src/ia64.c	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -42,5 +42,5 @@
 #include <userspace.h>
 #include <console/console.h>
-#include <proc/thread.h>
+#include <proc/uarg.h>
 
 void arch_pre_mm_init(void)
@@ -74,5 +74,5 @@
 
 /** Enter userspace and never return. */
-void userspace(uspace_arg_t *uarg)
+void userspace(uspace_arg_t *kernel_uarg)
 {
 	psr_t psr;
@@ -92,5 +92,9 @@
 	rsc.mode = 3;				/* eager mode */
 
-	switch_to_userspace(uarg->uspace_entry, uarg->uspace_stack+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), uarg->uspace_stack, psr.value, rsc.value);
+	switch_to_userspace((__address) kernel_uarg->uspace_entry,
+			    ((__address) kernel_uarg->uspace_stack)+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
+			    (__address) kernel_uarg->uspace_stack,
+			    (__address) kernel_uarg->uspace_uarg,
+			    psr.value, rsc.value);
 
 	while (1) {
Index: arch/mips32/include/asm.h
===================================================================
--- arch/mips32/include/asm.h	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ arch/mips32/include/asm.h	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -58,5 +58,5 @@
 extern void cpu_halt(void);
 extern void asm_delay_loop(__u32 t);
-extern void userspace_asm(__address ustack);
+extern void userspace_asm(__address ustack, __address uspace_uarg);
 
 #endif
Index: arch/mips32/src/mips32.c
===================================================================
--- arch/mips32/src/mips32.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ arch/mips32/src/mips32.c	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -38,4 +38,5 @@
 #include <memstr.h>
 #include <proc/thread.h>
+#include <proc/uarg.h>
 #include <print.h>
 
@@ -121,5 +122,5 @@
 __address supervisor_sp __attribute__ ((section (".text")));
 
-void userspace(uspace_arg_t *uarg)
+void userspace(uspace_arg_t *kernel_uarg)
 {
 	/* EXL=1, UM=1, IE=1 */
@@ -127,6 +128,6 @@
 					      cp0_status_um_bit |
 					      cp0_status_ie_enabled_bit));
-	cp0_epc_write(uarg->uspace_entry);
-	userspace_asm(uarg->uspace_stack+PAGE_SIZE);
+	cp0_epc_write((__address) kernel_uarg->uspace_entry);
+	userspace_asm(((__address) kernel_uarg->uspace_stack+PAGE_SIZE), (__address) kernel_uarg->uspace_uarg);
 	while (1)
 		;
Index: arch/mips32/src/start.S
===================================================================
--- arch/mips32/src/start.S	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ arch/mips32/src/start.S	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -227,5 +227,6 @@
 userspace_asm:
 	add $sp, $a0, 0
-	eret
-	nop
-
+	add $v0, $a1, 0
+	eret
+	nop
+
Index: generic/include/proc/thread.h
===================================================================
--- generic/include/proc/thread.h	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ generic/include/proc/thread.h	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -41,4 +41,5 @@
 #include <adt/list.h>
 #include <mm/slab.h>
+#include <proc/uarg.h>
 
 #define THREAD_STACK_SIZE	STACK_SIZE
@@ -118,10 +119,4 @@
 };
 
-/** Structure passed to uinit kernel thread as argument. */
-typedef struct uspace_arg {
-	__address uspace_entry;
-	__address uspace_stack;
-} uspace_arg_t;
-
 /** Thread list lock.
  *
@@ -150,6 +145,6 @@
 
 /** Thread syscall prototypes. */
-__native sys_thread_create(__address function, void *arg, void *stack, char *name);
-__native sys_thread_exit(int status);
+__native sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name);
+__native sys_thread_exit(int uspace_status);
 
 #endif
Index: generic/include/proc/uarg.h
===================================================================
--- generic/include/proc/uarg.h	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
+++ generic/include/proc/uarg.h	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __UARG_H__
+#define __UARG_H__
+
+/** Structure passed to uinit kernel thread as argument. */
+typedef struct uspace_arg {
+	void *uspace_entry;
+	void *uspace_stack;
+
+	void (* uspace_thread_function)();
+	void *uspace_thread_arg;
+	
+	struct uspace_arg *uspace_uarg;
+} uspace_arg_t;
+
+#endif
Index: generic/src/main/uinit.c
===================================================================
--- generic/src/main/uinit.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ generic/src/main/uinit.c	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -44,4 +44,7 @@
 	uarg.uspace_entry = ((uspace_arg_t *) arg)->uspace_entry;
 	uarg.uspace_stack = ((uspace_arg_t *) arg)->uspace_stack;
+	uarg.uspace_uarg = ((uspace_arg_t *) arg)->uspace_uarg;
+	uarg.uspace_thread_function = NULL;
+	uarg.uspace_thread_arg = NULL;
 
 	free((uspace_arg_t *) arg);
Index: generic/src/proc/task.c
===================================================================
--- generic/src/proc/task.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ generic/src/proc/task.c	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -30,7 +30,7 @@
 #include <proc/thread.h>
 #include <proc/task.h>
+#include <proc/uarg.h>
 #include <mm/as.h>
 #include <mm/slab.h>
-
 #include <synch/spinlock.h>
 #include <arch.h>
@@ -40,5 +40,4 @@
 #include <memstr.h>
 #include <print.h>
-
 #include <elf.h>
 
@@ -116,5 +115,5 @@
 	thread_t *t;
 	task_t *task;
-	uspace_arg_t *uarg;
+	uspace_arg_t *kernel_uarg;
 
 	as = as_create(0);
@@ -126,10 +125,13 @@
 	} 
 	
-	uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
-	uarg->uspace_entry = (__address) ((elf_header_t *) program_addr)->e_entry;
-	uarg->uspace_stack = USTACK_ADDRESS;
+	kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
+	kernel_uarg->uspace_entry = (void *) ((elf_header_t *) program_addr)->e_entry;
+	kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
+	kernel_uarg->uspace_thread_function = NULL;
+	kernel_uarg->uspace_thread_arg = NULL;
+	kernel_uarg->uspace_uarg = NULL;
 	
 	task = task_create(as, name);
-	t = thread_create(uinit, uarg, task, 0, "uinit");
+	t = thread_create(uinit, kernel_uarg, task, 0, "uinit");
 	
 	/*
Index: generic/src/proc/thread.c
===================================================================
--- generic/src/proc/thread.c	(revision 6c6a19e69c1590fe11db392c881db419fd28d8e1)
+++ generic/src/proc/thread.c	(revision 0f250f9bff41704344ca927ecc587c2eb450e9ee)
@@ -30,4 +30,5 @@
 #include <proc/thread.h>
 #include <proc/task.h>
+#include <proc/uarg.h>
 #include <mm/frame.h>
 #include <mm/page.h>
@@ -430,23 +431,22 @@
  *
  */
-__native sys_thread_create(__address function, void *arg, void *stack, char *name)
+__native sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name)
 {
         thread_t *t;
         char namebuf[THREAD_NAME_BUFLEN];
-	uspace_arg_t *uarg;
+	uspace_arg_t *kernel_uarg;		/* TODO: store kernel_uarg in thread_t */
 	__u32 tid;
 
-        copy_from_uspace(namebuf, name, THREAD_NAME_BUFLEN);
-	uarg = (uspace_arg_t *) malloc(sizeof(uarg), 0);
-	
-	uarg->uspace_entry = function;
-	uarg->uspace_stack = (__address) stack;
-
-        if ((t = thread_create(uinit, uarg, TASK, 0, namebuf))) {
+        copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN);
+
+	kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);	
+	copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t));
+
+        if ((t = thread_create(uinit, kernel_uarg, TASK, 0, namebuf))) {
 		tid = t->tid;
                 thread_ready(t);
 		return (__native) tid; 
         } else {
-                free(namebuf);
+		free(kernel_uarg);
         }
 
@@ -457,5 +457,5 @@
  *
  */
-__native sys_thread_exit(int status)
+__native sys_thread_exit(int uspace_status)
 {
         thread_exit();
