Index: trunk/kernel/mm/vmm.c
===================================================================
--- trunk/kernel/mm/vmm.c	(revision 672)
+++ trunk/kernel/mm/vmm.c	(revision 683)
@@ -1,4 +1,4 @@
 /*
- * vmm.c - virtual memory manager related operations definition.
+ * vmm.c - virtual memory manager related operations implementation.
  *
  * Authors   Ghassan Almaless (2008,2009,2010,2011,2012)
@@ -89,5 +89,6 @@
 
 // check ltid argument
-assert( __FUNCTION__, (ltid <= ((CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE) / CONFIG_VMM_STACK_SIZE)),
+assert( __FUNCTION__, 
+(ltid <= ((CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE) / CONFIG_VMM_STACK_SIZE)),
 "slot index %d too large for an user stack vseg", ltid );
 
@@ -107,10 +108,10 @@
     if( vseg == NULL )
    	{
-        // release lock protecting free lists
+ 
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n",
+__FUNCTION__ , local_cxy );
+#endif
         busylock_release( &mgr->lock );
-
-        printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n",
-        __FUNCTION__ , local_cxy );
-
         return NULL;
     }
@@ -346,10 +347,10 @@
     if( current_vseg == NULL )  // return failure 
     {
-        // release lock protecting free lists
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] %s cannot allocate ) %d page(s) in cluster %x\n",
+__FUNCTION__, npages , local_cxy );
+#endif
         busylock_release( &mgr->lock );
-
-        printk("\n[ERROR] %s cannot allocate ) %d page(s) in cluster %x\n",
-        __FUNCTION__, npages , local_cxy );
-
         return NULL;
     }
@@ -368,10 +369,10 @@
 	    if( new_vseg == NULL )
     	{
-	        // release lock protecting free lists
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n",
+__FUNCTION__ , local_cxy );
+#endif
             busylock_release( &mgr->lock );
-
-            printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n",
-            __FUNCTION__ , local_cxy );
-
             return NULL;
 	    }
@@ -517,5 +518,5 @@
                     XPTR( local_cxy , &vseg->xlist ) );
 
-}  // end vmm_attach_vseg_from_vsl()
+}  // end vmm_attach_vseg_to_vsl()
 
 ////////////////////////////////////////////////////////////////////////////////////////////
@@ -537,5 +538,5 @@
     xlist_unlink( XPTR( local_cxy , &vseg->xlist ) );
 
-}  // end vmm_detach_from_vsl()
+}  // end vmm_detach_vseg_from_vsl()
 
 ////////////////////////////////////////////
@@ -1290,6 +1291,10 @@
             if( child_vseg == NULL )   // release all allocated vsegs
             {
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] in %s : cannot create vseg for child in cluster %x\n",
+__FUNCTION__, local_cxy );
+#endif
                 vmm_destroy( child_process );
-                printk("\n[ERROR] in %s : cannot create vseg for child\n", __FUNCTION__ );
                 return -1;
             }
@@ -1338,6 +1343,10 @@
                     if( error )
                     {
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] in %s : cannot copy GPT\n",
+__FUNCTION__ );
+#endif
                         vmm_destroy( child_process );
-                        printk("\n[ERROR] in %s : cannot copy GPT\n", __FUNCTION__ );
                         return -1;
                     }
@@ -1357,20 +1366,4 @@
     remote_queuelock_release( parent_lock_xp );
 
-/* deprecated [AG] : this is already done by the vmm_user_init() funcfion
-
-    // initialize the child VMM STACK allocator
-    vmm_stack_init( child_vmm );
-
-    // initialize the child VMM MMAP allocator
-    vmm_mmap_init( child_vmm );
-
-    // initialize instrumentation counters
-	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
     child_vmm->args_vpn_base = (vpn_t)hal_remote_lpt(XPTR(parent_cxy, &parent_vmm->args_vpn_base));
@@ -1564,6 +1557,9 @@
         if( vseg == NULL )
         {
-            printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
-            __FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
+__FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
+#endif
             return NULL;
         }
@@ -1572,6 +1568,6 @@
         vseg->type = type;
         vseg->vmm  = vmm;
-        vseg->min  = vseg->vpn_base << CONFIG_PPM_PAGE_SHIFT;
-        vseg->max  = vseg->min + (vseg->vpn_size << CONFIG_PPM_PAGE_SHIFT);
+        vseg->min  = vseg->vpn_base << CONFIG_PPM_PAGE_ORDER;
+        vseg->max  = vseg->min + (vseg->vpn_size << CONFIG_PPM_PAGE_ORDER);
         vseg->cxy  = cxy;
 
@@ -1582,6 +1578,6 @@
     {
         // compute page index (in mapper) for first and last byte
-        vpn_t    vpn_min    = file_offset >> CONFIG_PPM_PAGE_SHIFT;
-        vpn_t    vpn_max    = (file_offset + size - 1) >> CONFIG_PPM_PAGE_SHIFT;
+        vpn_t    vpn_min    = file_offset >> CONFIG_PPM_PAGE_ORDER;
+        vpn_t    vpn_max    = (file_offset + size - 1) >> CONFIG_PPM_PAGE_ORDER;
 
         // compute offset in first page and number of pages
@@ -1594,6 +1590,9 @@
         if( vseg == NULL )
         {
-            printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
-            __FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
+__FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
+#endif
             return NULL;
         }
@@ -1602,5 +1601,5 @@
         vseg->type        = type;
         vseg->vmm         = vmm;
-        vseg->min         = (vseg->vpn_base << CONFIG_PPM_PAGE_SHIFT) + offset; 
+        vseg->min         = (vseg->vpn_base << CONFIG_PPM_PAGE_ORDER) + offset; 
         vseg->max         = vseg->min + size;
         vseg->file_offset = file_offset;
@@ -1615,5 +1614,5 @@
     {
         // compute number of required pages in virtual space
-        vpn_t npages = size >> CONFIG_PPM_PAGE_SHIFT;
+        vpn_t npages = size >> CONFIG_PPM_PAGE_ORDER;
         if( size & CONFIG_PPM_PAGE_MASK) npages++;
         
@@ -1623,6 +1622,9 @@
         if( vseg == NULL )
         {
-            printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
-            __FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
+__FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
+#endif
             return NULL;
         }
@@ -1631,6 +1633,6 @@
         vseg->type = type;
         vseg->vmm  = vmm;
-        vseg->min  = vseg->vpn_base << CONFIG_PPM_PAGE_SHIFT;
-        vseg->max  = vseg->min + (vseg->vpn_size << CONFIG_PPM_PAGE_SHIFT);
+        vseg->min  = vseg->vpn_base << CONFIG_PPM_PAGE_ORDER;
+        vseg->max  = vseg->min + (vseg->vpn_size << CONFIG_PPM_PAGE_ORDER);
         vseg->cxy  = cxy;
 
@@ -1640,6 +1642,6 @@
     else    // VSEG_TYPE_DATA, VSEG_TYPE_CODE or KERNEL vseg
     {
-        uint32_t vpn_min = base >> CONFIG_PPM_PAGE_SHIFT;
-        uint32_t vpn_max = (base + size - 1) >> CONFIG_PPM_PAGE_SHIFT;
+        uint32_t vpn_min = base >> CONFIG_PPM_PAGE_ORDER;
+        uint32_t vpn_max = (base + size - 1) >> CONFIG_PPM_PAGE_ORDER;
 
         // allocate vseg descriptor
@@ -1648,8 +1650,12 @@
 	    if( vseg == NULL )
 	    {
-            printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
-            __FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
+__FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
+#endif
             return NULL;
 	    }
+
         // initialize vseg
         vseg->type        = type;
@@ -1657,5 +1663,5 @@
         vseg->min         = base;
         vseg->max         = base + size;
-        vseg->vpn_base    = base >> CONFIG_PPM_PAGE_SHIFT;
+        vseg->vpn_base    = base >> CONFIG_PPM_PAGE_ORDER;
         vseg->vpn_size    = vpn_max - vpn_min + 1;
         vseg->file_offset = file_offset;
@@ -1672,8 +1678,11 @@
     if( existing_vseg != NULL )
     {
-        printk("\n[ERROR] in %s for process %x : new vseg %s [vpn_base %x / vpn_size %x]\n"
-               "        overlap existing vseg %s [vpn_base %x / vpn_size %x]\n",
-        __FUNCTION__ , process->pid, vseg_type_str(vseg->type), vseg->vpn_base, vseg->vpn_size, 
-        vseg_type_str(existing_vseg->type), existing_vseg->vpn_base, existing_vseg->vpn_size );
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] in %s for process %x : new vseg %s [vpn_base %x / vpn_size %x]\n"
+       "        overlap existing vseg %s [vpn_base %x / vpn_size %x]\n",
+__FUNCTION__ , process->pid, vseg_type_str(vseg->type), vseg->vpn_base, vseg->vpn_size, 
+vseg_type_str(existing_vseg->type), existing_vseg->vpn_base, existing_vseg->vpn_size );
+#endif
         vseg_free( vseg );
         return NULL;
@@ -1801,9 +1810,13 @@
     if( do_kmem_release )
     {
-        kmem_req_t req;
-        req.type = KMEM_PPM;
-        req.ptr  = GET_PTR( ppm_ppn2base( ppn ) );
-
-        kmem_remote_free( page_cxy , &req );
+        // get physical page order
+        uint32_t order = CONFIG_PPM_PAGE_ORDER +
+                         hal_remote_l32( XPTR( page_cxy , &page_ptr->order ));
+
+        // get physical page base 
+        void * base = GET_PTR( ppm_ppn2base( ppn ) );
+
+        // release physical page
+        kmem_remote_free( page_cxy , base , order );
 
 #if DEBUG_VMM_PPN_RELEASE
@@ -1855,6 +1868,6 @@
 #endif
 
-    // loop on PTEs in GPT to unmap all mapped PTE
-	for( vpn = vpn_min ; vpn < vpn_max ; vpn++ )
+    // the loop on PTEs in GPT to unmap all mapped PTEs 
+    for( vpn = vpn_min ; vpn < vpn_max ; vpn++ )
     {
         // get ppn and attr
@@ -1942,6 +1955,6 @@
     intptr_t min          = new_base;
     intptr_t max          = new_base + new_size;
-    vpn_t    new_vpn_min  = min >> CONFIG_PPM_PAGE_SHIFT;
-    vpn_t    new_vpn_max  = (max - 1) >> CONFIG_PPM_PAGE_SHIFT;
+    vpn_t    new_vpn_min  = min >> CONFIG_PPM_PAGE_ORDER;
+    vpn_t    new_vpn_max  = (max - 1) >> CONFIG_PPM_PAGE_ORDER;
 
     // build extended pointer on GPT
@@ -2082,10 +2095,10 @@
         if( ref_cxy == local_cxy )    // local is ref => return error
         {
-            printk("\n[ERROR] in %s : vaddr %x in process %x out of segment\n",
-            __FUNCTION__, vaddr, process->pid );
-
-            // release local VSL lock
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] in %s : vaddr %x in process %x out of segment\n",
+__FUNCTION__, vaddr, process->pid );
+#endif
             remote_queuelock_release( loc_lock_xp );
-
             return -1;
         }
@@ -2103,11 +2116,11 @@
             if( ref_vseg == NULL )  // vseg not found => return error
             {
-                // release both VSL locks 
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] in %s : vaddr %x in process %x out of segment\n",
+__FUNCTION__, vaddr, process->pid );
+#endif
                 remote_queuelock_release( loc_lock_xp );
                 remote_queuelock_release( ref_lock_xp );
-
-                printk("\n[ERROR] in %s : vaddr %x in process %x out of segment\n",
-                __FUNCTION__, vaddr, process->pid );
-
                 return -1;
             }
@@ -2119,11 +2132,11 @@
                 if( loc_vseg == NULL )   // no memory => return error
                 {
-                    printk("\n[ERROR] in %s : vaddr %x in process %x / no memory\n",
-                    __FUNCTION__, vaddr, process->pid );
-
-                    // release both VSL locks
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] in %s : vaddr %x in process %x / no memory\n",
+__FUNCTION__, vaddr, process->pid );
+#endif
                     remote_queuelock_release( ref_lock_xp );
                     remote_queuelock_release( loc_lock_xp );
-
                     return -1;
                 }
@@ -2158,11 +2171,12 @@
 //////////////////////////////////////////////////////////////////////////////////////
 // This static function compute the target cluster to allocate a physical page
-// for a given <vpn> in a given <vseg>, allocates the page and returns an extended 
-// pointer on the allocated page descriptor.
+// for a given <vpn> in a given <vseg>, allocates the physical page from a local
+// or remote cluster (depending on the vseg type), and returns an extended pointer
+// on the allocated page descriptor.
 // The vseg cannot have the FILE type.
 //////////////////////////////////////////////////////////////////////////////////////
 // @ vseg   : local pointer on vseg.
 // @ vpn    : unmapped vpn.
-// @ return an extended pointer on the allocated page descriptor.
+// @ return xptr on page descriptor if success / return XPTR_NULL if failure
 //////////////////////////////////////////////////////////////////////////////////////
 static xptr_t vmm_page_allocate( vseg_t * vseg,
@@ -2207,13 +2221,16 @@
     }
 
-    // allocate one small physical page from target cluster
-    kmem_req_t req;
-    req.type  = KMEM_PPM;
-    req.order = 0;
-    req.flags = AF_ZERO;
-
     // get local pointer on page base
-    void * ptr = kmem_remote_alloc( page_cxy , &req );
-
+    void * ptr = kmem_remote_alloc( page_cxy , CONFIG_PPM_PAGE_ORDER , AF_ZERO );
+
+    if( ptr == NULL )
+    {
+
+#if DEBUG_VMM_ERROR
+printk("\n[ERROR] in %s : cannot allocate memory from cluster %x\n",
+__FUNCTION__, page_cxy );
+#endif
+        return XPTR_NULL;
+    }     
     // get extended pointer on page descriptor
     page_xp = ppm_base2page( XPTR( page_cxy , ptr ) );
@@ -2291,5 +2308,5 @@
         
             // compute missing page offset in vseg
-            uint32_t offset = page_id << CONFIG_PPM_PAGE_SHIFT;
+            uint32_t offset = page_id << CONFIG_PPM_PAGE_ORDER;
 
             // compute missing page offset in .elf file
@@ -2427,5 +2444,5 @@
     // get local vseg (access to reference VSL can be required)
     error = vmm_get_vseg( process, 
-                          (intptr_t)vpn<<CONFIG_PPM_PAGE_SHIFT,
+                          (intptr_t)vpn<<CONFIG_PPM_PAGE_ORDER,
                           &vseg );
     if( error )
@@ -2752,5 +2769,5 @@
     // get local vseg
     error = vmm_get_vseg( process, 
-                          (intptr_t)vpn<<CONFIG_PPM_PAGE_SHIFT,
+                          (intptr_t)vpn<<CONFIG_PPM_PAGE_ORDER,
                           &vseg );
     if( error )
