Index: trunk/kernel/mm/vmm.c
===================================================================
--- trunk/kernel/mm/vmm.c	(revision 623)
+++ trunk/kernel/mm/vmm.c	(revision 624)
@@ -76,14 +76,12 @@
     vmm_t   * vmm = &process->vmm;
 
-    // initialize local list of vsegs 
+    // initialize VSL (empty)
     vmm->vsegs_nr = 0;
 	xlist_root_init( XPTR( local_cxy , &vmm->vsegs_root ) );
 	remote_rwlock_init( XPTR( local_cxy , &vmm->vsegs_lock ) , LOCK_VMM_VSL );
 
-assert( ((CONFIG_VMM_KENTRY_SIZE + CONFIG_VMM_ARGS_SIZE + CONFIG_VMM_ENVS_SIZE) 
-<= CONFIG_VMM_ELF_BASE) , "UTILS zone too small\n" );
-
-assert( (CONFIG_THREADS_MAX_PER_CLUSTER <= 32) ,
-"no more than 32 threads per cluster for a single process\n");
+assert( ((CONFIG_VMM_ARGS_SIZE + CONFIG_VMM_ENVS_SIZE) <= 
+         (CONFIG_VMM_ELF_BASE - CONFIG_VMM_UTILS_BASE)) ,
+         "UTILS zone too small\n" );
 
 assert( ((CONFIG_VMM_STACK_SIZE * CONFIG_THREADS_MAX_PER_CLUSTER) <=
@@ -92,6 +90,5 @@
 
     // register args vseg in VSL
-    base = (CONFIG_VMM_KENTRY_BASE + 
-            CONFIG_VMM_KENTRY_SIZE ) << CONFIG_PPM_PAGE_SHIFT;
+    base = CONFIG_VMM_UTILS_BASE << CONFIG_PPM_PAGE_SHIFT;
     size = CONFIG_VMM_ARGS_SIZE << CONFIG_PPM_PAGE_SHIFT;
 
@@ -114,7 +111,5 @@
 
     // register the envs vseg in VSL
-    base = (CONFIG_VMM_KENTRY_BASE + 
-            CONFIG_VMM_KENTRY_SIZE +
-            CONFIG_VMM_ARGS_SIZE   ) << CONFIG_PPM_PAGE_SHIFT;
+    base = (CONFIG_VMM_UTILS_BASE + CONFIG_VMM_ARGS_SIZE) << CONFIG_PPM_PAGE_SHIFT;
     size = CONFIG_VMM_ENVS_SIZE << CONFIG_PPM_PAGE_SHIFT;
 
@@ -148,5 +143,5 @@
     remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT );
 
-    // update process VMM with kernel vsegs
+    // update process VMM with kernel vsegs as required by the hardware architecture
     error = hal_vmm_kernel_update( process );
 
@@ -185,54 +180,4 @@
 }  // end vmm_init()
 
-//////////////////////////////////////
-void vmm_display( process_t * process,
-                  bool_t      mapping )
-{
-    vmm_t * vmm = &process->vmm;
-    gpt_t * gpt = &vmm->gpt;
-
-    printk("\n***** VSL and GPT(%x) for process %x in cluster %x\n\n",
-    process->vmm.gpt.ptr , process->pid , local_cxy );
-
-    // get lock protecting the VSL and the GPT
-    remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->vsegs_lock ) );
-    remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->gpt_lock ) );
-
-    // scan the list of vsegs
-    xptr_t         root_xp = XPTR( local_cxy , &vmm->vsegs_root );
-    xptr_t         iter_xp;
-    xptr_t         vseg_xp;
-    vseg_t       * vseg;
-    XLIST_FOREACH( root_xp , iter_xp )
-    {
-        vseg_xp = XLIST_ELEMENT( iter_xp , vseg_t , xlist );
-        vseg    = GET_PTR( vseg_xp );
-
-        printk(" - %s : base = %X / size = %X / npages = %d\n",
-        vseg_type_str( vseg->type ) , vseg->min , vseg->max - vseg->min , vseg->vpn_size );
-
-        if( mapping )
-        {
-            vpn_t    vpn;
-            ppn_t    ppn;
-            uint32_t attr;
-            vpn_t    base = vseg->vpn_base;
-            vpn_t    size = vseg->vpn_size;
-            for( vpn = base ; vpn < (base+size) ; vpn++ )
-            {
-                hal_gpt_get_pte( XPTR( local_cxy , gpt ) , vpn , &attr , &ppn );
-                if( attr & GPT_MAPPED )
-                {
-                    printk("    . vpn = %X / attr = %X / ppn = %X\n", vpn , attr , ppn );
-                }
-            }
-        }
-    }
-
-    // release the locks
-    remote_rwlock_rd_release( XPTR( local_cxy , &vmm->vsegs_lock ) );
-    remote_rwlock_rd_release( XPTR( local_cxy , &vmm->gpt_lock ) );
-
-}  // vmm_display()
 
 //////////////////////////////////////////
@@ -248,4 +193,7 @@
     // update vseg descriptor
     vseg->vmm = vmm;
+
+    // increment vsegs number
+    vmm->vsegs_nr++;
 
     // add vseg in vmm list
@@ -735,5 +683,4 @@
 
     // copy base addresses from parent VMM to child VMM
-    child_vmm->kent_vpn_base = (vpn_t)hal_remote_lpt(XPTR(parent_cxy, &parent_vmm->kent_vpn_base));
     child_vmm->args_vpn_base = (vpn_t)hal_remote_lpt(XPTR(parent_cxy, &parent_vmm->args_vpn_base));
     child_vmm->envs_vpn_base = (vpn_t)hal_remote_lpt(XPTR(parent_cxy, &parent_vmm->envs_vpn_base));
@@ -773,5 +720,5 @@
 #if (DEBUG_VMM_DESTROY & 1 )
 if( DEBUG_VMM_DESTROY < cycle )
-vmm_display( process , true );
+hal_vmm_display( process , true );
 #endif
 
@@ -785,7 +732,5 @@
     // (don't use a FOREACH for item deletion in xlist)
 
-uint32_t count = 0;
-
-	while( !xlist_is_empty( root_xp ) && (count < 10 ) )
+	while( !xlist_is_empty( root_xp ) )
 	{
         // get pointer on first vseg in VSL
@@ -801,6 +746,4 @@
 __FUNCTION__ , vseg_type_str( vseg->type ), vseg->vpn_base, vseg->vpn_size );
 #endif
-
-count++;
 
 	}
@@ -1093,4 +1036,5 @@
     // check collisions
     vseg = vmm_check_conflict( process , vpn_base , vpn_size );
+
     if( vseg != NULL )
     {
@@ -1162,5 +1106,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
+    uint32_t    vseg_type;  // vseg type
 
 #if DEBUG_VMM_DELETE_VSEG
@@ -1197,12 +1141,12 @@
 
     // get relevant vseg infos
-    type    = vseg->type;
-    vpn_min = vseg->vpn_base;
-    vpn_max = vpn_min + vseg->vpn_size;
+    vseg_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++ )
     {
-        // get GPT entry
+        // get ppn and attr from GPT entry
         hal_gpt_get_pte( XPTR( local_cxy , gpt ) , vpn , &attr , &ppn );
 
@@ -1217,15 +1161,9 @@
             hal_gpt_reset_pte( gpt , vpn );
 
-            // the allocated page is not released to KMEM for kernel vseg
-            if( (type != VSEG_TYPE_KCODE) && 
-                (type != VSEG_TYPE_KDATA) && 
-                (type != VSEG_TYPE_KDEV ) )
+            // the allocated page is not released to for kernel vseg
+            if( (vseg_type != VSEG_TYPE_KCODE) && 
+                (vseg_type != VSEG_TYPE_KDATA) && 
+                (vseg_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 );
@@ -1233,4 +1171,7 @@
                 page_ptr = GET_PTR( page_xp );
 
+// FIXME This code must be re-written, as the actual release depends on vseg type,
+// the reference cluster, the page refcount and/or the forks counter...
+
                 // get extended pointers on forks and lock fields
                 forks_xp = XPTR( page_cxy , &page_ptr->forks );
@@ -1245,8 +1186,16 @@
                 if( forks )  // decrement pending forks counter
                 {
+                    // update forks counter
                     hal_remote_atomic_add( forks_xp , -1 );
+
+                    // release the lock protecting the page
+                    remote_busylock_release( lock_xp );
                 }  
                 else         // release physical page to relevant cluster
                 {
+                    // release the lock protecting the page
+                    remote_busylock_release( lock_xp );
+
+                    // release the page to kmem
                     if( page_cxy == local_cxy )   // local cluster
                     {
@@ -1266,6 +1215,4 @@
                 }
 
-                // release the lock protecting the page
-                remote_busylock_release( lock_xp );
             }
         }
