Index: trunk/kernel/mm/vmm.h
===================================================================
--- trunk/kernel/mm/vmm.h	(revision 567)
+++ trunk/kernel/mm/vmm.h	(revision 585)
@@ -89,5 +89,5 @@
 /*********************************************************************************************
  * This structure defines the Virtual Memory Manager for a given process in a given cluster.
- * This local VMM provides four main services:
+ * This local VMM implements four main services:
  * 1) It contains the local copy of vseg list (VSL), only complete in referrence.
  * 2) It contains the local copy of the generic page table (GPT), only complete in reference.
@@ -96,9 +96,12 @@
  ******************************************************a**************************************
  * Implementation notes:
- * 1. The VSL contains only local vsegs, but it is implemented as an xlist, and protected by
+ * 1. In most clusters, the VSL and GPT are only partial copies of the reference VSL and GPT
+ *    structures, stored in the reference cluster.
+ * 2. The VSL contains only local vsegs, but it is implemented as an xlist, and protected by
  *    a remote_rwlock, because it can be accessed by a thread running in a remote cluster.
  *    An exemple is the vmm_fork_copy() function.
- * 2. In most clusters, the VSL and GPT are only partial copies of the reference VSL and GPT
- *    structures, stored in the reference cluster.
+ * 3. The GPT in the reference cluster can be directly accessed by remote threads to handle
+ *    false page-fault (page is mapped in the reference GPT, but the PTE copy is missing
+ *    in the local GPT). It is also protected by a remote_rwlock. 
  ********************************************************************************************/
 
@@ -106,7 +109,8 @@
 {
 	remote_rwlock_t  vsegs_lock;         /*! lock protecting the local VSL                  */
-	xlist_entry_t    vsegs_root;         /*! VSL root (VSL only complete in reference)      */
+	xlist_entry_t    vsegs_root;         /*! Virtual Segment List (complete in reference)   */
 	uint32_t         vsegs_nr;           /*! total number of local vsegs                    */
 
+    remote_rwlock_t  gpt_lock;           /*! lock protecting the local GPT                  */
     gpt_t            gpt;                /*! Generic Page Table (complete in reference)     */
 
@@ -213,5 +217,5 @@
 
 /*********************************************************************************************
- * This global function modifies a GPT entry identified  by the <process> and <vpn> 
+ * This global function modifies a GPT entry identified by the <process> and <vpn> 
  * arguments in all clusters containing a process copy.
  * It must be called by a thread running in the reference cluster.
@@ -352,57 +356,56 @@
 
 /*********************************************************************************************
- * This function is called by the generic exception handler in case of page-fault,
- * or copy-on-write event locally detected for a given <vpn> in a given <process>
- * as defined by the <is_cow> argument.
- * 1) For a Page-Fault:
- * - If the local cluster is the reference, or for the STACK and CODE segment types,
- *   it call directly the vmm_get_pte() function to access the local VMM.
- * - Otherwise, it send a RPC_VMM_GET_PTE to the reference cluster to get the missing 
- *   PTE attributes and PPN.
- * This function check that the missing VPN belongs to a registered vseg, allocates
- * a new physical page if required, and updates the local page table. 
- * 2) For a Copy-On-Write:
- * - If no pending fork, it reset the COW flag and set the WRITE flag in the reference
- *   GPT entry, and in all the GPT copies.
- * - If there is a pending fork, it allocates a new physical page from the cluster defined 
- *   by the vseg type, copies the old physical page content to the new physical page,
- *   and decrements the pending_fork counter in old physical page descriptor.
+ * This function is called by the generic exception handler in case of page-fault event,
+ * detected for a given <vpn> in a given <process> in any cluster. 
+ * It checks the missing VPN and returns an user error if it is not in a registered vseg.
+ * For a legal VPN, there is actually 3 cases:
+ * 1) if the missing VPN belongs to a private vseg (STACK or CODE segment types, non
+ *    replicated in all clusters), it allocates a new physical page, computes the attributes,
+ *    depending on vseg type, and updates directly the local GPT.
+ * 2) if the missing VPN belongs to a public vseg, it can be a false page-fault, when the VPN
+ *    is mapped in the reference GPT, but not in the local GPT. For this false page-fault,
+ *    the local GPT is simply updated from the reference GPT.
+ * 3) if the missing VPN is public, and unmapped in the reference GPT, it's a true page fault.
+ *    The calling thread  allocates a new physical page, computes the attributes, depending
+ *    on vseg type, and updates directly (without RPC) the local GPT and the reference GPT.
+ *    Other GPT copies  will updated on demand.
+ * In the three cases, concurrent accesses to the GPT are handled, thanks to the 
+ * remote_rwlock protecting each GPT copy.
  *********************************************************************************************
  * @ process   : pointer on local process descriptor copy.
- * @ vpn       : VPN of the missing or faulting PTE.
- * @ is_cow    : Copy-On-Write event if true / Page-fault if false.
- * @ returns 0 if success / returns ENOMEM if no memory or illegal VPN.
+ * @ vpn       : VPN of the missing PTE.
+ * @ returns EXCP_NON_FATAL / EXCP_USER_ERROR / EXCP_KERNEL_PANIC after analysis
  ********************************************************************************************/
 error_t vmm_handle_page_fault( struct process_s * process,
-                               vpn_t              vpn,
-                               bool_t             is_cow );
-
-/*********************************************************************************************
- * This function is called by the vmm_handle_page_fault() to handle both the "page-fault",
- * and the "copy-on_write" events for a given <vpn> in a given <process>, as defined
- * by the <is_cow> argument. 
- * The vseg containing the searched VPN must be registered in the reference VMM.
- * - for an page-fault, it allocates the missing physical page from the target cluster
- *   defined by the vseg type, initializes it, and updates the reference GPT, but not
- *   the copies GPT, that will be updated on demand. 
- * - for a copy-on-write, it allocates a new physical page from the target cluster,
- *   initialise it from the old physical page, and updates the reference GPT and all
- *   the GPT copies, for coherence. 
- * It calls the RPC_PMEM_GET_PAGES to get the new physical page when the target cluster
- * is not the local cluster, 
- * It returns in the <attr> and <ppn> arguments the accessed or modified PTE.
- *********************************************************************************************
- * @ process   : [in] pointer on process descriptor.
- * @ vpn       : [in] VPN defining the missing PTE.
- * @ is_cow    : [in] "copy_on_write" if true / "page_fault" if false.
- * @ attr      : [out] PTE attributes.
- * @ ppn       : [out] PTE ppn.
- * @ returns 0 if success / returns ENOMEM if error.
- ********************************************************************************************/
-error_t vmm_get_pte( struct process_s * process,
-                     vpn_t              vpn,
-                     bool_t             is_cow,
-                     uint32_t         * attr,
-                     ppn_t            * ppn );
+                               vpn_t              vpn );
+
+/*********************************************************************************************
+ * This function is called by the generic exception handler in case of copy-on-write event, 
+ * detected for a given <vpn> in a given <process> in any cluster.
+ * It returns a kernel panic if VPN is not in a registered vseg or is not mapped.
+ * For a legal mapped vseg there is two cases:
+ * 1) If the missing VPN belongs to a private vseg (STACK or CODE segment types, non
+ *    replicated in all clusters), it access the local GPT to get the current PPN and ATTR.
+ *    It access the forks counter in the current physical page descriptor.
+ *    If there is a pending fork, it allocates a new physical page from the cluster defined 
+ *    by the vseg type, copies the old physical page content to the new physical page,
+ *    and decrements the pending_fork counter in old physical page descriptor.
+ *    Finally, it reset the COW flag and set the WRITE flag in local GPT.
+ * 2) If the missing VPN is public, it access the reference GPT to get the current PPN and
+ *    ATTR. It access the forks counter in the current physical page descriptor.
+ *    If there is a pending fork, it allocates a new physical page from the cluster defined 
+ *    by the vseg type, copies the old physical page content to the new physical page,
+ *    and decrements the pending_fork counter in old physical page descriptor.
+ *    Finally it calls the vmm_global_update_pte() function to reset the COW flag and set
+ *    the WRITE flag in all the GPT copies, using a RPC if the reference cluster is remote.
+ * In both cases, concurrent accesses to the GPT are handled, thanks to the 
+ * remote_rwlock protecting each GPT copy.
+ *********************************************************************************************
+ * @ process   : pointer on local process descriptor copy.
+ * @ vpn       : VPN of the faulting PTE.
+ * @ returns EXCP_NON_FATAL / EXCP_USER_ERROR / EXCP_KERNEL_PANIC after analysis
+ ********************************************************************************************/
+error_t vmm_handle_cow( struct process_s * process,
+                        vpn_t              vpn );
 
 /*********************************************************************************************
