Index: trunk/kernel/mm/vmm.c
===================================================================
--- trunk/kernel/mm/vmm.c	(revision 621)
+++ trunk/kernel/mm/vmm.c	(revision 623)
@@ -59,5 +59,4 @@
 {
     error_t   error;
-    vseg_t  * vseg_kentry;
     vseg_t  * vseg_args;
     vseg_t  * vseg_envs;
@@ -91,25 +90,4 @@
 (CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE)) ,
 "STACK zone too small\n");
-
-    // register kentry vseg in VSL
-    base = CONFIG_VMM_KENTRY_BASE << CONFIG_PPM_PAGE_SHIFT;
-    size = CONFIG_VMM_KENTRY_SIZE << CONFIG_PPM_PAGE_SHIFT;
-
-    vseg_kentry = vmm_create_vseg( process,
-                                   VSEG_TYPE_CODE,
-                                   base,
-                                   size,
-                                   0,             // file_offset unused
-                                   0,             // file_size unused
-                                   XPTR_NULL,     // mapper_xp unused
-                                   local_cxy );
-
-    if( vseg_kentry == NULL )
-    {
-        printk("\n[ERROR] in %s : cannot register kentry vseg\n", __FUNCTION__ );
-        return -1;
-    }
-
-    vmm->kent_vpn_base = base;
 
     // register args vseg in VSL
@@ -162,15 +140,20 @@
 
     if( error ) 
-    printk("\n[ERROR] in %s : cannot create GPT\n", __FUNCTION__ );
+    {
+        printk("\n[ERROR] in %s : cannot create GPT\n", __FUNCTION__ );
+        return -1;
+    }
 
     // initialize GPT lock
     remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT );
 
-    // architecture specic GPT initialisation
-    // (For TSAR, identity map the kentry_vseg)
-    error = hal_vmm_init( vmm );
-
-    if( error ) 
-    printk("\n[ERROR] in %s : cannot initialize GPT\n", __FUNCTION__ );
+    // update process VMM with kernel vsegs
+    error = hal_vmm_kernel_update( process );
+
+    if( error )
+    { 
+        printk("\n[ERROR] in %s : cannot update GPT for kernel vsegs\n", __FUNCTION__ );
+        return -1;
+    }
 
     // initialize STACK allocator
@@ -326,6 +309,7 @@
     }
 
-    // release physical memory allocated for vseg descriptor if no MMAP type
-    if( (type != VSEG_TYPE_ANON) && (type != VSEG_TYPE_FILE) && (type != VSEG_TYPE_REMOTE) )
+    // release physical memory allocated for vseg if no MMAP and no kernel type
+    if( (type != VSEG_TYPE_ANON) && (type != VSEG_TYPE_FILE) && (type != VSEG_TYPE_REMOTE) &&
+        (type != VSEG_TYPE_KCODE) && (type != VSEG_TYPE_KDATA) && (type != VSEG_TYPE_KDEV) )
     {
         vseg_free( vseg );
@@ -606,5 +590,5 @@
     child_vmm->vsegs_nr = 0;
 
-    // create child GPT
+    // create the child GPT
     error = hal_gpt_create( &child_vmm->gpt );
 
@@ -639,6 +623,7 @@
 #endif
 
-        // all parent vsegs - but STACK - must be copied in child VSL
-        if( type != VSEG_TYPE_STACK )
+        // all parent vsegs - but STACK and kernel vsegs - must be copied in child VSL
+        if( (type != VSEG_TYPE_STACK) && (type != VSEG_TYPE_KCODE) &&
+            (type != VSEG_TYPE_KDATA) && (type != VSEG_TYPE_KDEV) )
         {
             // allocate memory for a new child vseg
@@ -726,11 +711,10 @@
     remote_rwlock_rd_release( parent_lock_xp );
 
-    // initialize child GPT (architecture specic)
-    // => For TSAR, identity map the kentry_vseg
-    error = hal_vmm_init( child_vmm );
+    // update child VMM with kernel vsegs
+    error = hal_vmm_kernel_update( child_process );
 
     if( error )
     {
-        printk("\n[ERROR] in %s : cannot create GPT\n", __FUNCTION__ );
+        printk("\n[ERROR] in %s : cannot update child VMM\n", __FUNCTION__ );
         return -1;
     }
@@ -1098,5 +1082,5 @@
         base = vpn_base << CONFIG_PPM_PAGE_SHIFT;
     }
-    else    // VSEG_TYPE_DATA or VSEG_TYPE_CODE
+    else    // VSEG_TYPE_DATA, VSEG_TYPE_CODE or KERNEL vseg
     {
         uint32_t vpn_min = base >> CONFIG_PPM_PAGE_SHIFT;
@@ -1178,4 +1162,5 @@
     xptr_t      lock_xp;    // extended pointer on lock protecting forks counter
     uint32_t    forks;      // actual number of pendinf forks
+    uint32_t    type;       // vseg type
 
 #if DEBUG_VMM_DELETE_VSEG
@@ -1190,5 +1175,10 @@
     process = cluster_get_local_process_from_pid( pid );
 
-    if( process == NULL ) return;
+    if( process == NULL )
+    {
+        printk("\n[ERRORR] in %s : cannot get local process descriptor\n",
+        __FUNCTION__ );
+        return;
+    }
 
     // get pointers on local process VMM an GPT
@@ -1199,9 +1189,17 @@
     vseg = vmm_vseg_from_vaddr( vmm , vaddr );
 
-    if( vseg == NULL ) return;
-
-    // loop to invalidate all vseg PTEs in GPT
+    if( vseg == NULL )
+    {
+        printk("\n[ERRORR] in %s : cannot get vseg descriptor\n",
+        __FUNCTION__ );
+        return;
+    }
+
+    // get relevant vseg infos
+    type    = vseg->type;
     vpn_min = vseg->vpn_base;
     vpn_max = vpn_min + vseg->vpn_size;
+
+    // loop to invalidate all vseg PTEs in GPT
 	for( vpn = vpn_min ; vpn < vpn_max ; vpn++ )
     {
@@ -1216,17 +1214,18 @@
 printk("- unmap vpn %x / ppn %x / vseg %s \n" , vpn , ppn, vseg_type_str(vseg->type) );
 #endif
-
-// check small page
-assert( (attr & GPT_SMALL) , "an user vseg must use small pages" );
-
             // unmap GPT entry in local GPT
             hal_gpt_reset_pte( gpt , vpn );
 
-            // handle pending forks counter if
-            // 1) not identity mapped
-            // 2) reference cluster
-            if( ((vseg->flags & VSEG_IDENT)  == 0) &&
-                (GET_CXY( process->ref_xp ) == local_cxy) )
+            // the allocated page is not released to KMEM for kernel vseg
+            if( (type != VSEG_TYPE_KCODE) && 
+                (type != VSEG_TYPE_KDATA) && 
+                (type != VSEG_TYPE_KDEV ) )
             {
+
+// FIXME This code must be completely re-written, as the actual release must depend on
+// - the vseg type
+// - the reference cluster
+// - the page refcount and/or the forks counter
+
                 // get extended pointer on physical page descriptor
                 page_xp  = ppm_ppn2page( ppn );
@@ -1238,7 +1237,10 @@
                 lock_xp  = XPTR( page_cxy , &page_ptr->lock );
 
+                // get the lock protecting the page
                 remote_busylock_acquire( lock_xp );
+
                 // get pending forks counter
                 forks = hal_remote_l32( forks_xp );
+
                 if( forks )  // decrement pending forks counter
                 {
@@ -1263,4 +1265,6 @@
 #endif
                 }
+
+                // release the lock protecting the page
                 remote_busylock_release( lock_xp );
             }
@@ -1311,4 +1315,5 @@
     // return failure
     remote_rwlock_rd_release( lock_xp );
+
     return NULL;
 
@@ -1325,4 +1330,12 @@
     vpn_t     vpn_max;
 
+#if DEBUG_VMM_RESIZE_VSEG
+uint32_t   cycle = (uint32_t)hal_get_cycles();
+thread_t * this  = CURRENT_THREAD;
+if( DEBUG_VMM_RESIZE_VSEG < cycle )
+printk("\n[%s] thread[%x,%x] enter / process %x / base %x / size %d / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, process->pid, base, size, cycle );
+#endif
+
     // get pointer on process VMM
     vmm_t * vmm = &process->vmm;
@@ -1334,24 +1347,45 @@
 	vseg_t * vseg = vmm_vseg_from_vaddr( vmm , base );
 
-	if( vseg == NULL)  return EINVAL;
-
-    // get extended pointer on VSL lock
-    xptr_t lock_xp = XPTR( local_cxy , &vmm->vsegs_lock );
-
-    // get lock protecting VSL
-	remote_rwlock_wr_acquire( lock_xp );
-
+	if( vseg == NULL)
+    {
+        printk("\n[ERROR] in %s : vseg(%x,%d) not found\n",
+        __FUNCTION__, base , size );
+        return -1;
+    }
+
+    // resize depends on unmapped region base and size
 	if( (vseg->min > addr_min) || (vseg->max < addr_max) )        // not included in vseg
     {
+        printk("\n[ERROR] in %s : unmapped region[%x->%x[ not included in vseg[%x->%x[\n",
+        __FUNCTION__, addr_min, addr_max, vseg->min, vseg->max );
+
         error = -1;
     }
 	else if( (vseg->min == addr_min) && (vseg->max == addr_max) )  // vseg must be deleted
     {
+
+#if( DEBUG_VMM_RESIZE_VSEG & 1 )
+if( DEBUG_VMM_RESIZE_VSEG < cycle )
+printk("\n[%s] unmapped region[%x->%x[ equal vseg[%x->%x[\n",
+__FUNCTION__, addr_min, addr_max, vseg->min, vseg->max );
+#endif
         vmm_delete_vseg( process->pid , vseg->min );
+
+#if( DEBUG_VMM_RESIZE_VSEG & 1 )
+if( DEBUG_VMM_RESIZE_VSEG < cycle )
+printk("\n[%s] thread[%x,%x] deleted vseg\n",
+__FUNCTION__, this->process->pid, this->trdid );
+#endif
         error = 0;
     }
 	else if( vseg->min == addr_min )                               // vseg must be resized
     {
-        // update vseg base address
+
+#if( DEBUG_VMM_RESIZE_VSEG & 1 )
+if( DEBUG_VMM_RESIZE_VSEG < cycle )
+printk("\n[%s] unmapped region[%x->%x[ included in vseg[%x->%x[\n",
+__FUNCTION__, addr_min, addr_max, vseg->min, vseg->max );
+#endif
+        // update vseg min address
         vseg->min = addr_max;
 
@@ -1361,8 +1395,20 @@
         vseg->vpn_base = vpn_min;
         vseg->vpn_size = vpn_max - vpn_min + 1;
+
+#if( DEBUG_VMM_RESIZE_VSEG & 1 )
+if( DEBUG_VMM_RESIZE_VSEG < cycle )
+printk("\n[%s] thread[%x,%x] changed vseg_min\n",
+__FUNCTION__, this->process->pid, this->trdid );
+#endif
         error = 0;
     }
 	else if( vseg->max == addr_max )                              // vseg must be resized
     {
+
+#if( DEBUG_VMM_RESIZE_VSEG & 1 )
+if( DEBUG_VMM_RESIZE_VSEG < cycle )
+printk("\n[%s] unmapped region[%x->%x[ included in vseg[%x->%x[\n",
+__FUNCTION__, addr_min, addr_max, vseg->min, vseg->max );
+#endif
         // update vseg max address
         vseg->max = addr_min;
@@ -1373,8 +1419,21 @@
         vseg->vpn_base = vpn_min;
         vseg->vpn_size = vpn_max - vpn_min + 1;
+
+#if( DEBUG_VMM_RESIZE_VSEG & 1 )
+if( DEBUG_VMM_RESIZE_VSEG < cycle )
+printk("\n[%s] thread[%x,%x] changed vseg_max\n",
+__FUNCTION__, this->process->pid, this->trdid );
+#endif
         error = 0;
+
     }
     else                                                          // vseg cut in three regions 
     {
+
+#if( DEBUG_VMM_RESIZE_VSEG & 1 )
+if( DEBUG_VMM_RESIZE_VSEG < cycle )
+printk("\n[%s] unmapped region[%x->%x[ included in vseg[%x->%x[\n",
+__FUNCTION__, addr_min, addr_max, vseg->min, vseg->max );
+#endif
         // resize existing vseg
         vseg->max = addr_min;
@@ -1396,10 +1455,19 @@
                                vseg->cxy ); 
 
-        if( new == NULL ) error = EINVAL;
+#if( DEBUG_VMM_RESIZE_VSEG & 1 )
+if( DEBUG_VMM_RESIZE_VSEG < cycle )
+printk("\n[%s] thread[%x,%x] replaced vseg by two smal vsegs\n",
+__FUNCTION__, this->process->pid, this->trdid );
+#endif
+
+        if( new == NULL ) error = -1;
         else              error = 0;
     }
 
-    // release VMM lock
-	remote_rwlock_wr_release( lock_xp );
+#if DEBUG_VMM_RESIZE_VSEG
+if( DEBUG_VMM_RESIZE_VSEG < cycle )
+printk("\n[%s] thread[%x,%x] exit / process %x / base %x / size %d / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, process->pid, base, size, cycle );
+#endif
 
 	return error;
