* per VM-area/task. A VM area is any part of the process virtual memory
  * space that has a special rule for the page-fault handlers (ie a shared
  * library, the executable area etc).
+ *
+ * Only explicitly marked struct members may be accessed by RCU readers before
+ * getting a stable reference.
  */
 struct vm_area_struct {
        /* The first cache line has the info for VMA tree walking. */
 #endif
        };
 
-       struct mm_struct *vm_mm;        /* The address space we belong to. */
+       /*
+        * The address space we belong to.
+        * Unstable RCU readers are allowed to read this.
+        */
+       struct mm_struct *vm_mm;
        pgprot_t vm_page_prot;          /* Access permissions of this VMA. */
 
        /*
        };
 
 #ifdef CONFIG_PER_VMA_LOCK
-       /* Flag to indicate areas detached from the mm->mm_mt tree */
+       /*
+        * Flag to indicate areas detached from the mm->mm_mt tree.
+        * Unstable RCU readers are allowed to read this.
+        */
        bool detached;
 
        /*
         * slowpath.
         */
        int vm_lock_seq;
+       /* Unstable RCU readers are allowed to read this. */
        struct vma_lock *vm_lock;
 #endif
 
 
        if (!vma_start_read(vma))
                goto inval;
 
-       /* Check since vm_start/vm_end might change before we lock the VMA */
-       if (unlikely(address < vma->vm_start || address >= vma->vm_end))
-               goto inval_end_read;
-
        /* Check if the VMA got isolated after we found it */
        if (vma->detached) {
                vma_end_read(vma);
                /* The area was replaced with another one */
                goto retry;
        }
+       /*
+        * At this point, we have a stable reference to a VMA: The VMA is
+        * locked and we know it hasn't already been isolated.
+        * From here on, we can access the VMA without worrying about which
+        * fields are accessible for RCU readers.
+        */
+
+       /* Check since vm_start/vm_end might change before we lock the VMA */
+       if (unlikely(address < vma->vm_start || address >= vma->vm_end))
+               goto inval_end_read;
 
        rcu_read_unlock();
        return vma;