Index: trunk/kernel/mm/vmm.c
===================================================================
--- trunk/kernel/mm/vmm.c	(revision 634)
+++ trunk/kernel/mm/vmm.c	(revision 635)
@@ -49,7 +49,7 @@
 #include <hal_exception.h>
 
-//////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////
 //   Extern global variables
-//////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////
 
 extern  process_t  process_zero;      // allocated in cluster.c 
@@ -286,14 +286,7 @@
 }  // end vmm_detach_from_vsl()
 
-
-
-
 ////////////////////////////////////////////
 error_t vmm_user_init( process_t * process )
 {
-    vseg_t  * vseg_args;
-    vseg_t  * vseg_envs;
-    intptr_t  base;
-    intptr_t  size;
     uint32_t  i;
 
@@ -319,4 +312,9 @@
 "STACK zone too small\n");
 
+    // initialize the lock protecting the VSL 
+	remote_rwlock_init( XPTR( local_cxy , &vmm->vsl_lock ) , LOCK_VMM_VSL );
+
+
+/*
     // register "args" vseg in VSL
     base = CONFIG_VMM_UTILS_BASE << CONFIG_PPM_PAGE_SHIFT;
@@ -358,5 +356,5 @@
 
     vmm->envs_vpn_base = base;
-
+*/
     // initialize STACK allocator
     vmm->stack_mgr.bitmap   = 0;
@@ -375,5 +373,10 @@
 
     // initialize instrumentation counters
-	vmm->pgfault_nr = 0;
+	vmm->false_pgfault_nr    = 0;
+	vmm->local_pgfault_nr    = 0;
+	vmm->global_pgfault_nr   = 0;
+	vmm->false_pgfault_cost  = 0;
+	vmm->local_pgfault_cost  = 0;
+	vmm->global_pgfault_cost = 0;
 
     hal_fence();
@@ -398,6 +401,10 @@
 
 #if DEBUG_VMM_USER_RESET
-uint32_t cycle = (uint32_t)hal_get_cycles();
+uint32_t   cycle;
 thread_t * this = CURRENT_THREAD;
+#endif
+
+#if (DEBUG_VMM_USER_RESET & 1 )
+cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_VMM_USER_RESET < cycle )
 printk("\n[%s] thread[%x,%x] enter for process %x in cluster %x / cycle %d\n",
@@ -407,5 +414,5 @@
 #if (DEBUG_VMM_USER_RESET & 1 )
 if( DEBUG_VMM_USER_RESET < cycle )
-hal_vmm_display( process , true );
+hal_vmm_display( XPTR( local_cxy , process ) , true );
 #endif
 
@@ -478,4 +485,9 @@
 #endif
 
+#if (DEBUG_VMM_USER_RESET & 1 )
+if( DEBUG_VMM_USER_RESET < cycle )
+hal_vmm_display( XPTR( local_cxy , process ) , true );
+#endif
+
 }  // end vmm_user_reset()
 
@@ -503,10 +515,7 @@
 thread_t * this = CURRENT_THREAD;
 if( DEBUG_VMM_UPDATE_PTE < cycle )
-printk("\n[%s] thread[%x,%x] enter for process %x / vpn %x / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, process->pid , vpn , cycle );
-#endif
-
-// check cluster is reference
-assert( (GET_CXY( process->ref_xp ) == local_cxy) , "not called in reference cluster\n");
+printk("\n[%s] thread[%x,%x] enter for process %x / vpn %x / attr %x / ppn %x / ycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, process->pid, vpn, attr, ppn, cycle );
+#endif
 
     // get extended pointer on root of process copies xlist in owner cluster
@@ -517,4 +526,7 @@
     process_root_xp  = XPTR( owner_cxy , process_root_ptr );
 
+// check local cluster is owner cluster
+assert( (owner_cxy == local_cxy) , "must be called in owner cluster\n");
+
     // loop on destination process copies
     XLIST_FOREACH( process_root_xp , process_iter_xp )
@@ -525,7 +537,7 @@
         remote_process_cxy = GET_CXY( remote_process_xp );
 
-#if (DEBUG_VMM_UPDATE_PTE & 0x1)
+#if (DEBUG_VMM_UPDATE_PTE & 1)
 if( DEBUG_VMM_UPDATE_PTE < cycle )
-printk("\n[%s] threadr[%x,%x] handling vpn %x for process %x in cluster %x\n",
+printk("\n[%s] thread[%x,%x] handling vpn %x for process %x in cluster %x\n",
 __FUNCTION__, this->process->pid, this->trdid, vpn, process->pid, remote_process_cxy );
 #endif
@@ -545,4 +557,8 @@
 #endif
 
+#if (DEBUG_VMM_UPDATE_PTE & 1)
+hal_vmm_display( process , true );
+#endif
+
 }  // end vmm_global_update_pte()
 
@@ -570,4 +586,7 @@
     cxy_t           owner_cxy;
     lpid_t          owner_lpid;
+
+    // get target process PID
+    pid = process->pid;
 
 #if DEBUG_VMM_SET_COW
@@ -576,10 +595,15 @@
 if( DEBUG_VMM_SET_COW < cycle )
 printk("\n[%s] thread[%x,%x] enter for process %x / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, process->pid , cycle );
+__FUNCTION__, this->process->pid, this->trdid, pid , cycle );
+#endif
+
+#if (DEBUG_VMM_SET_COW & 1)
+if( DEBUG_VMM_SET_COW < cycle )
+hal_vmm_display( process , true );
 #endif
 
 // check cluster is reference
-assert( (GET_CXY( process->ref_xp ) == local_cxy) ,
-"local cluster is not process reference cluster\n");
+assert( (XPTR( local_cxy , process ) == process->ref_xp),
+"local cluster must be process reference cluster\n");
 
     // get pointer on reference VMM
@@ -587,5 +611,4 @@
 
     // get extended pointer on root of process copies xlist in owner cluster
-    pid              = process->pid;
     owner_cxy        = CXY_FROM_PID( pid );
     owner_lpid       = LPID_FROM_PID( pid );
@@ -596,8 +619,8 @@
     vseg_root_xp  = XPTR( local_cxy , &vmm->vsegs_root ); 
 
-    // loop on destination process copies
+    // loop on target process copies
     XLIST_FOREACH( process_root_xp , process_iter_xp )
     {
-        // get cluster and local pointer on remote process
+        // get cluster and local pointer on remote process copy
         remote_process_xp  = XLIST_ELEMENT( process_iter_xp , process_t , copies_list );
         remote_process_ptr = GET_PTR( remote_process_xp );
@@ -606,6 +629,6 @@
 #if (DEBUG_VMM_SET_COW & 1)
 if( DEBUG_VMM_SET_COW < cycle )
-printk("\n[%s] thread[%x,%x] handling process %x in cluster %x\n",
-__FUNCTION__, this->process->pid, this->trdid, process->pid , remote_process_cxy );
+printk("\n[%s] thread[%x,%x] (%x) handles process %x in cluster %x\n",
+__FUNCTION__, this->process->pid, this->trdid, this, pid, remote_process_cxy );
 #endif
 
@@ -620,7 +643,4 @@
             vseg     = GET_PTR( vseg_xp );
 
-assert( (GET_CXY( vseg_xp ) == local_cxy) ,
-"all vsegs in reference VSL must be local\n" );
-
             // get vseg type, base and size
             uint32_t type     = vseg->type;
@@ -630,5 +650,5 @@
 #if (DEBUG_VMM_SET_COW & 1)
 if( DEBUG_VMM_SET_COW < cycle )
-printk("\n[%s] thread[%x,%x] handling vseg %s / vpn_base = %x / vpn_size = %x\n",
+printk("\n[%s] thread[%x,%x] found vseg %s / vpn_base = %x / vpn_size = %x\n",
 __FUNCTION__, this->process->pid, this->trdid, vseg_type_str(type), vpn_base, vpn_size );
 #endif
@@ -653,7 +673,13 @@
 
                 // atomically increment pending forks counter in physical pages,
-                // for all vseg pages that are mapped in reference cluster 
+                // this is only done once, when handling the reference copy 
                 if( remote_process_cxy == local_cxy )
                 {
+
+#if (DEBUG_VMM_SET_COW & 1)
+if( DEBUG_VMM_SET_COW < cycle )
+printk("\n[%s] thread[%x,%x] handles vseg %s / vpn_base = %x / vpn_size = %x\n",
+__FUNCTION__, this->process->pid, this->trdid, vseg_type_str(type), vpn_base, vpn_size );
+#endif
                     // scan all pages in vseg 
                     for( vpn = vpn_base ; vpn < (vpn_base + vpn_size) ; vpn++ )
@@ -684,4 +710,10 @@
                         }
                     }   // end loop on vpn
+
+#if (DEBUG_VMM_SET_COW & 1)
+if( DEBUG_VMM_SET_COW < cycle )
+printk("\n[%s] thread[%x,%x] completes vseg %s / vpn_base = %x / vpn_size = %x\n",
+__FUNCTION__, this->process->pid, this->trdid, vseg_type_str(type), vpn_base, vpn_size );
+#endif
                 }   // end if local
             }   // end if vseg type
@@ -713,12 +745,7 @@
     vseg_t    * child_vseg;
     uint32_t    type;
-    bool_t      cow;
     vpn_t       vpn;            
     vpn_t       vpn_base;
     vpn_t       vpn_size;
-    xptr_t      page_xp;        // extended pointer on page descriptor
-    page_t    * page_ptr;
-    cxy_t       page_cxy;
-    xptr_t      forks_xp;       // extended pointer on forks counter in page descriptor
     xptr_t      parent_root_xp;
     bool_t      mapped; 
@@ -740,19 +767,4 @@
     parent_vmm = &parent_process->vmm; 
     child_vmm  = &child_process->vmm;
-
-    // initialize the lock protecting the child VSL 
-	remote_rwlock_init( XPTR( local_cxy , &child_vmm->vsl_lock ) , LOCK_VMM_VSL );
-
-    // initialize the child VSL as empty
-    xlist_root_init( XPTR( local_cxy, &child_vmm->vsegs_root ) );
-    child_vmm->vsegs_nr = 0;
-
-    // create an empty child GPT
-    error = hal_gpt_create( &child_vmm->gpt );
-    if( error )
-    {
-        printk("\n[ERROR] in %s : cannot create GPT\n", __FUNCTION__ );
-        return -1;
-    }
 
     // build extended pointer on parent VSL root and lock
@@ -820,5 +832,5 @@
             {
                 // activate the COW for DATA, ANON, REMOTE vsegs only
-                cow = ( type != VSEG_TYPE_FILE );
+                // cow = ( type != VSEG_TYPE_FILE );
 
                 vpn_base = child_vseg->vpn_base;
@@ -832,7 +844,7 @@
                                               XPTR( parent_cxy , &parent_vmm->gpt ),
                                               vpn,
-                                              cow,
-                                              &ppn,
-                                              &mapped );
+                                              false,      // does not handle COW flag
+                                              &ppn,       // unused
+                                              &mapped );  // unused
                     if( error )
                     {
@@ -842,25 +854,4 @@
                     }
 
-                    // increment pending forks counter in page if mapped
-                    if( mapped )
-                    {
-                        // get pointers and cluster on page descriptor
-                        page_xp  = ppm_ppn2page( ppn );
-                        page_cxy = GET_CXY( page_xp );
-                        page_ptr = GET_PTR( page_xp );
-
-                        // get extended pointers on "forks" and "lock"
-                        forks_xp = XPTR( page_cxy , &page_ptr->forks );
-                        lock_xp  = XPTR( page_cxy , &page_ptr->lock );
-
-                        // get lock protecting "forks" counter
-                        remote_busylock_acquire( lock_xp );
-
-                        // increment "forks"
-                        hal_remote_atomic_add( forks_xp , 1 );
-
-                        // release lock protecting "forks" counter
-                        remote_busylock_release( lock_xp );
-
 #if DEBUG_VMM_FORK_COPY
 cycle = (uint32_t)hal_get_cycles();
@@ -869,5 +860,4 @@
 __FUNCTION__ , this->process->pid, this->trdid , vpn , cycle );
 #endif
-                    }
                 }
             }   // end if no code & no stack
@@ -877,13 +867,4 @@
     // release the parent VSL lock in read mode
     remote_rwlock_rd_release( parent_lock_xp );
-
-    // update child VMM with kernel vsegs
-    error = hal_vmm_kernel_update( child_process );
-
-    if( error )
-    {
-        printk("\n[ERROR] in %s : cannot update child VMM\n", __FUNCTION__ );
-        return -1;
-    }
 
     // initialize the child VMM STACK allocator
@@ -902,5 +883,10 @@
 
     // initialize instrumentation counters
-	child_vmm->pgfault_nr    = 0;
+	child_vmm->false_pgfault_nr    = 0;
+	child_vmm->local_pgfault_nr    = 0;
+	child_vmm->global_pgfault_nr   = 0;
+	child_vmm->false_pgfault_cost  = 0;
+	child_vmm->local_pgfault_cost  = 0;
+	child_vmm->global_pgfault_cost = 0;
 
     // copy base addresses from parent VMM to child VMM
@@ -933,6 +919,6 @@
 
 #if DEBUG_VMM_DESTROY
-uint32_t cycle = (uint32_t)hal_get_cycles();
-thread_t * this = CURRENT_THREAD;
+uint32_t   cycle = (uint32_t)hal_get_cycles();
+thread_t * this  = CURRENT_THREAD;
 if( DEBUG_VMM_DESTROY < cycle )
 printk("\n[%s] thread[%x,%x] enter for process %x in cluster %x / cycle %d\n",
@@ -942,5 +928,5 @@
 #if (DEBUG_VMM_DESTROY & 1 )
 if( DEBUG_VMM_DESTROY < cycle )
-hal_vmm_display( process , true );
+hal_vmm_display( XPTR( local_cxy, process ) , true );
 #endif
 
@@ -1062,5 +1048,5 @@
 vseg_t * vmm_create_vseg( process_t   * process,
 	                      vseg_type_t   type,
-                          intptr_t      base,
+                          intptr_t      base,         // ltid for VSEG_TYPE_STACK
 	                      uint32_t      size,
                           uint32_t      file_offset,
@@ -1074,10 +1060,11 @@
 	error_t      error;
 
-#if DEBUG_VMM_CREATE_VSEG
+#if (DEBUG_VMM_CREATE_VSEG & 1)
 thread_t * this  = CURRENT_THREAD;
 uint32_t   cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_VMM_CREATE_VSEG < cycle )
-printk("\n[%s] thread[%x,%x] enter for process %x / %s / cxy %x / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, process->pid, vseg_type_str(type), cxy, cycle );
+printk("\n[%s] thread[%x,%x] enter / process %x / %s / base %x / cxy %x / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid,
+process->pid, vseg_type_str(type), base, cxy, cycle );
 #endif
 
@@ -1171,5 +1158,5 @@
 	}
 
-#if DEBUG_VMM_CREATE_VSEG
+#if (DEBUG_VMM_CREATE_VSEG & 1)
 if( DEBUG_VMM_CREATE_VSEG < cycle )
 printk("\n[%s] thread[%x,%x] : base %x / size %x / vpn_base %x / vpn_size %x\n",
@@ -1204,6 +1191,7 @@
 cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_VMM_CREATE_VSEG < cycle )
-printk("\n[%s] thread[%x,%x] exit / %s / cxy %x / cycle %d\n",
-__FUNCTION__, this->process->pid, this->trdid, vseg_type_str(type), cxy, cycle );
+printk("\n[%s] thread[%x,%x] exit / process %x / %s / base %x / cxy %x / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, 
+process->pid, vseg_type_str(type), base, cxy, cycle );
 #endif
 
@@ -1685,4 +1673,5 @@
     xptr_t       page_xp;
     cxy_t        page_cxy;
+    page_t     * page_ptr;
     uint32_t     index;
 
@@ -1711,12 +1700,14 @@
     }
 
-    // allocate a 4 Kbytes physical page from target cluster
-    page_xp = ppm_remote_alloc_pages( page_cxy , 0 );
+    // allocate one small physical page from target cluster
+    page_ptr = ppm_remote_alloc_pages( page_cxy , 0 );
+
+    page_xp = XPTR( page_cxy , page_ptr );
 
 #if DEBUG_VMM_PAGE_ALLOCATE
 cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_VMM_PAGE_ALLOCATE < cycle )
-printk("\n[%s] thread[%x,%x] exit for vpn %x / ppn %x / cluster %x / cycle %d\n",
-__FUNCTION__ , this->process->pid, this->trdid, vpn, ppm_page2ppn(page_xp), page_cxy, cycle );
+printk("\n[%s] thread[%x,%x] exit for vpn %x / ppn %x / cycle %d\n",
+__FUNCTION__ , this->process->pid, this->trdid, vpn, ppm_page2ppn(page_xp), cycle );
 #endif
 
@@ -1741,6 +1732,5 @@
 uint32_t   cycle = (uint32_t)hal_get_cycles();
 thread_t * this  = CURRENT_THREAD;
-// if( DEBUG_VMM_GET_ONE_PPN < cycle )
-if( vpn == 0x40B )
+if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
 printk("\n[%s] thread[%x,%x] enter for vpn %x / type %s / page_id  %d / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, vpn, vseg_type_str(type), page_id, cycle );
@@ -1769,5 +1759,5 @@
         page_xp = vmm_page_allocate( vseg , vpn );
 
-        if( page_xp == XPTR_NULL ) return ENOMEM;
+        if( page_xp == XPTR_NULL ) return -1;
 
         // initialise missing page from .elf file mapper for DATA and CODE types
@@ -1788,6 +1778,5 @@
 
 #if (DEBUG_VMM_GET_ONE_PPN & 0x1)
-// if( DEBUG_VMM_GET_ONE_PPN < cycle )
-if( vpn == 0x40B )
+if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
 printk("\n[%s] thread[%x,%x] for vpn = %x / elf_offset = %x\n",
 __FUNCTION__, this->process->pid, this->trdid, vpn, elf_offset );
@@ -1803,6 +1792,5 @@
 
 #if (DEBUG_VMM_GET_ONE_PPN & 0x1)
-// if( DEBUG_VMM_GET_ONE_PPN < cycle )
-if( vpn == 0x40B )
+if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
 printk("\n[%s] thread[%x,%x] for vpn  %x / fully in BSS\n",
 __FUNCTION__, this->process->pid, this->trdid, vpn );
@@ -1821,6 +1809,5 @@
 
 #if (DEBUG_VMM_GET_ONE_PPN & 0x1)
-// if( DEBUG_VMM_GET_ONE_PPN < cycle )
-if( vpn == 0x40B )
+if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
 printk("\n[%s] thread[%x,%x] for vpn  %x / fully in mapper\n",
 __FUNCTION__, this->process->pid, this->trdid, vpn );
@@ -1839,6 +1826,5 @@
 
 #if (DEBUG_VMM_GET_ONE_PPN & 0x1)
-// if( DEBUG_VMM_GET_ONE_PPN < cycle )
-if( vpn == 0x40B )
+if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
 printk("\n[%s] thread[%x,%x] for vpn  %x / both mapper & BSS\n"
 "      %d bytes from mapper / %d bytes from BSS\n",
@@ -1874,7 +1860,6 @@
 #if DEBUG_VMM_GET_ONE_PPN
 cycle = (uint32_t)hal_get_cycles();
-// if( DEBUG_VMM_GET_ONE_PPN < cycle )
-if( vpn == 0x40B )
-printk("\n[%s] thread[%x,%x] exit for vpn %x / ppn %x / cycle\n",
+if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) )
+printk("\n[%s] thread[%x,%x] exit for vpn %x / ppn %x / cycle %d\n",
 __FUNCTION__ , this->process->pid, this->trdid , vpn , *ppn, cycle );
 #endif
@@ -1906,5 +1891,5 @@
 
 #if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] thread[%x,%x] enter for vpn %x / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, vpn, start_cycle );
@@ -1912,6 +1897,6 @@
 
 #if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
-hal_vmm_display( this->process , false );
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
+hal_vmm_display( this->process , true );
 #endif
 
@@ -1928,6 +1913,6 @@
     }
 
-#if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] thread[%x,%x] found vseg %s\n",
 __FUNCTION__, this->process->pid, this->trdid, vseg_type_str(vseg->type) );
@@ -1950,7 +1935,7 @@
     }
 
-#if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
-printk("\n[%s] thread[%x,%x] locked vpn %x in cluster %x / cycle %d\n",
+#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
+printk("\n[%s] thread[%x,%x] locked vpn %x in cluster %x\n",
 __FUNCTION__, this->process->pid, this->trdid, vpn, local_cxy );
 #endif
@@ -1970,8 +1955,9 @@
         {
 
-#if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
-printk("\n[%s] thread[%x,%x] access local gpt : cxy %x / ref_cxy %x / type %s\n",
-__FUNCTION__, this->process->pid, this->trdid, local_cxy, ref_cxy, vseg_type_str(vseg->type) );
+#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
+printk("\n[%s] thread[%x,%x] access local gpt : cxy %x / ref_cxy %x / type %s / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid,
+local_cxy, ref_cxy, vseg_type_str(vseg->type), (uint32_t)hal_get_cycles() );
 #endif
             // allocate and initialise a physical page 
@@ -2008,5 +1994,5 @@
 
 #if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] thread[%x,%x] handled local pgfault / ppn %x / attr %x / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, ppn, attr, end_cycle );
@@ -2026,8 +2012,9 @@
         {
 
-#if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
-printk("\n[%s] thread[%x,%x] access ref gpt : cxy %x / ref_cxy %x / type %s\n",
-__FUNCTION__, this->process->pid, this->trdid, local_cxy, ref_cxy, vseg_type_str(vseg->type) );
+#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
+printk("\n[%s] thread[%x,%x] access ref gpt : cxy %x / ref_cxy %x / type %s / cycle %d\n",
+__FUNCTION__, this->process->pid, this->trdid, 
+local_cxy, ref_cxy, vseg_type_str(vseg->type), (uint32_t)hal_get_cycles() );
 #endif
             // build extended pointer on reference GPT
@@ -2050,6 +2037,6 @@
             }
 
-#if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] thread[%x,%x] get pte from ref gpt / attr %x / ppn %x\n",
 __FUNCTION__, this->process->pid, this->trdid, ref_attr, ref_ppn );
@@ -2065,6 +2052,6 @@
                                  ref_ppn );
 
-#if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] thread[%x,%x] updated local gpt for a false pgfault\n",
 __FUNCTION__, this->process->pid, this->trdid );
@@ -2074,6 +2061,6 @@
                 hal_gpt_unlock_pte( ref_gpt_xp, vpn );
                              
-#if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+#if (DEBUG_VMM_HANDLE_PAGE_FAULT &1)
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] thread[%x,%x] unlock the ref gpt after a false pgfault\n",
 __FUNCTION__, this->process->pid, this->trdid );
@@ -2085,5 +2072,5 @@
 
 #if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] thread[%x,%x] handled false pgfault / ppn %x / attr %x / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, ref_ppn, ref_attr, end_cycle );
@@ -2120,6 +2107,6 @@
                 if( vseg->flags & VSEG_CACHE ) attr |= GPT_CACHABLE;
 
-#if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] thread[%x,%x] build a new PTE for a true pgfault\n",
 __FUNCTION__, this->process->pid, this->trdid );
@@ -2132,6 +2119,6 @@
                                  ppn );
 
-#if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
+if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] thread[%x,%x] set new PTE in ref gpt for a true page fault\n",
 __FUNCTION__, this->process->pid, this->trdid );
@@ -2150,5 +2137,5 @@
 
 #if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] thread[%x,%x] handled global pgfault / ppn %x / attr %x / cycle %d\n",
 __FUNCTION__, this->process->pid, this->trdid, ppn, attr, end_cycle );
@@ -2173,5 +2160,5 @@
 
 #if DEBUG_VMM_HANDLE_PAGE_FAULT
-if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn == vpn) )
+if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) )
 printk("\n[%s] handled by another thread / vpn %x / ppn %x / attr %x / cycle %d\n",
 __FUNCTION__, vpn, ppn, attr, end_cycle );
@@ -2212,5 +2199,5 @@
 #endif
 
-#if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)
+#if ((DEBUG_VMM_HANDLE_COW & 3) == 3 )
 hal_vmm_display( process , true );
 #endif
@@ -2352,5 +2339,5 @@
 #if(DEBUG_VMM_HANDLE_COW & 1)
 if( DEBUG_VMM_HANDLE_COW < cycle )
-printk("\n[%s] thread[%x,%x]  no pending forks / keep existing PPN %x\n",
+printk("\n[%s] thread[%x,%x] no pending forks / keep existing PPN %x\n",
 __FUNCTION__, this->process->pid, this->trdid, old_ppn );
 #endif
@@ -2360,4 +2347,10 @@
     // build new_attr : set WRITABLE, reset COW, reset LOCKED
     new_attr = (((old_attr | GPT_WRITABLE) & (~GPT_COW)) & (~GPT_LOCKED));
+
+#if(DEBUG_VMM_HANDLE_COW & 1)
+if( DEBUG_VMM_HANDLE_COW < cycle )
+printk("\n[%s] thread[%x,%x] new_attr %x / new_ppn %x\n",
+__FUNCTION__, this->process->pid, this->trdid, new_attr, new_ppn );
+#endif
 
     // update the relevant GPT(s)
@@ -2366,5 +2359,5 @@
     if( (vseg->type == VSEG_TYPE_STACK) || (vseg->type == VSEG_TYPE_CODE) )
     {
-        // set the new PTE2
+        // set new PTE in local gpt
         hal_gpt_set_pte( gpt_xp,
                          vpn,
@@ -2398,4 +2391,8 @@
 #endif
 
+#if ((DEBUG_VMM_HANDLE_COW & 3) == 3)
+hal_vmm_display( process , true );
+#endif
+
      return EXCP_NON_FATAL;
 
