Index: trunk/kernel/syscalls/sys_thread_create.c
===================================================================
--- trunk/kernel/syscalls/sys_thread_create.c	(revision 438)
+++ trunk/kernel/syscalls/sys_thread_create.c	(revision 440)
@@ -53,5 +53,5 @@
 	trdid_t          trdid;            // created thread identifier
 	process_t      * process;          // pointer on local process descriptor
-	paddr_t          paddr;            // unused, required by vmm_v2p_translate()
+	vseg_t         * vseg;             // required for user space checking
     cxy_t            target_cxy;       // target cluster identifier
 	error_t          error;
@@ -67,12 +67,27 @@
 tm_start = hal_get_cycles();
 if( DEBUG_SYS_THREAD_CREATE < tm_start )
-printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n"
-__FUNCTION__ , parent , process->pid, (uint32_t)tm_start );
-#endif
-
-	// check user_attr in user space & copy to kernel space
+printk("\n[DBG] %s : thread %x (cxy %x) enter / process %x / cycle %d\n",
+__FUNCTION__, parent, local_cxy, process->pid, (uint32_t)tm_start );
+#endif
+
+    // check trdid buffer in user space
+    error = vmm_get_vseg( process , (intptr_t)trdid_ptr , &vseg );
+
+    if ( error )
+    {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : trdid buffer unmapped %x / thread %x / process %x\n",
+__FUNCTION__ , (intptr_t)trdid_ptr, parent->trdid, process->pid );
+vmm_display( process , false );
+#endif
+		parent->errno = EINVAL;
+		return -1;
+    }
+
+	// check user_attr buffer in user space & copy to kernel space
     if( user_attr != NULL )
     {
-	    error = vmm_v2p_translate( false , user_attr , &paddr );
+	    error = vmm_get_vseg( process , (intptr_t)user_attr , &vseg );
 
 	    if( error )
@@ -80,5 +95,7 @@
 
 #if DEBUG_SYSCALLS_ERROR
-printk("\n[ERROR] in %s : user_attr unmapped\n", __FUNCTION__ );
+printk("\n[ERROR] in %s : user_attr buffer unmapped %x / thread %x / process %x\n",
+__FUNCTION__ , (intptr_t)user_attr , parent->trdid , process->pid );
+vmm_display( process , false );
 #endif
 		    parent->errno = EINVAL;
@@ -90,30 +107,37 @@
 
 	// check start_func in user space
-	error = vmm_v2p_translate( false , start_func , &paddr );
-
-	if( error )
-	{
-
-#if DEBUG_SYSCALLS_ERROR
-printk("\n[ERROR] in %s : start_func unmapped\n", __FUNCTION__ );
-#endif
-		parent->errno = EINVAL;
-		return -1;
-	}
-
-	// check start_arg in user space
-	if( start_arg != NULL ) error = vmm_v2p_translate( false , start_arg , &paddr );
-
-	if( error )
-	{
-
-#if DEBUG_SYSCALLS_ERROR
-printk("\n[ERROR] in %s : start_arg unmapped\n", __FUNCTION__ );
-#endif
-		parent->errno = EINVAL;
-		return -1;
-	}
-
-	// check / define attributes an target_cxy
+	error = vmm_get_vseg( process , (intptr_t)start_func , &vseg );
+
+    if( error )
+    {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : start_func unmapped %x / thread %x / process %x\n",
+__FUNCTION__ , (intptr_t)start_func , parent->trdid , process->pid );
+vmm_display( process , false );
+#endif
+        parent->errno = EINVAL;
+	    return -1;
+	}
+
+	// check start_arg buffer in user space
+	if( start_arg != NULL )
+    {
+        error = vmm_get_vseg( process , (intptr_t)start_arg , &vseg );
+
+   	    if( error )
+	    {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : start_arg buffer unmapped %x / thread %x / process %x\n",
+__FUNCTION__ , (intptr_t)start_arg , parent->trdid , process->pid );
+vmm_display( process , false );
+#endif
+		    parent->errno = EINVAL;
+		    return -1;
+        }
+	}
+
+    // define attributes and target_cxy
     if( user_attr != NULL )                      // user defined attributes
     {
@@ -125,5 +149,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-printk("\n[ERROR] in %s : illegal target cluster = %x\n", __FUNCTION__ , kern_attr.cxy );
+printk("\n[ERROR] in %s : illegal target cluster = %x / thread %x / process %x\n",
+__FUNCTION__ , kern_attr.cxy, parent->trdid, process->pid );
 #endif
 			    parent->errno = EINVAL;
@@ -175,7 +200,9 @@
 
 #if DEBUG_SYSCALLS_ERROR
-printk("\n[ERROR] in %s : cannot create thread\n", __FUNCTION__ );
-#endif
-		return ENOMEM;
+printk("\n[ERROR] in %s : cannot create new thread / thread %x / process %x\n",
+__FUNCTION__ , parent->trdid, process->pid );
+#endif
+		parent->errno = ENOMEM;
+		return -1;
 	}
 
@@ -184,11 +211,4 @@
 	hal_copy_to_uspace( trdid_ptr , &trdid , sizeof(pthread_t) );
 
-    // register child in parent if required
-    if( user_attr != NULL )
-    {
-	    if( (kern_attr.attributes & PT_ATTR_DETACH) == 0 )
-	        thread_child_parent_link( parent_xp , child_xp );
-    }
-
     // activate new thread
 	thread_unblock( child_xp , THREAD_BLOCKED_GLOBAL );
@@ -199,6 +219,6 @@
 tm_end = hal_get_cycles();
 if( DEBUG_SYS_THREAD_CREATE < tm_end )
-printk("\n[DBG] %s : thread %x created thread %x for process %x in cluster %x / cycle %d\n"
-__FUNCTION__, parent, child_ptr, process->pid, target_cxy, (uint32_t)tm_end );
+printk("\n[DBG] %s : thread %x (cxy %x) created thread %x (cxy %x) / process %x / cycle %d\n",
+__FUNCTION__, parent, local_cxy, child_ptr, target_cxy, process->pid, (uint32_t)tm_end );
 #endif
 
