title: vm_flags vs vm_page_prot
body: <p>I am working with linux kernel 2.6.38 and have a question about two fields of a <code>vm_area_struct</code>, <code>vm_flags</code> and <code>vm_page_prot</code>. If I mmap private anonymous memory to be readable and writable, and then I print out the two fields of the created vm_area_struct, I see that the low 8 bits of <code>vm_flags</code> are 0x73 and the low 8 bits of <code>vm_page_prot</code> are 0x25. I am running x86 32-bit, and my constants are</p>
  
  <pre><code>VM_READ=0x01
  VM_WRITE=0x02
  VM_EXEC=0x04
  </code></pre>
  
  <p>Thus, it appears my vm_flags says the memory is read/write but the vm_page_prot says it is only readable (the executable flag is meaningless on x86). My understanding is that <code>vm_page_prot</code> is supposed to reflect the protection of page table entries of pages in the VM region. As I go onto read/write memory in the mmaped area in userspace, the page faulting mechanism work correctly, setting the PTE's of the appropriate pages. Some pages (if I only read from them) are mapped to the special zero page frame with the PTE set to <em>read only</em> while other pages that are written to have the PTE set to <em>read/write</em>. This is expected behavior...in fact, from mm/memory.c:</p>
  
  <pre><code>static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
      unsigned long address, pte_t *page_table, pmd_t *pmd,
      unsigned int flags)
  {
      ...
      entry = pte_mkspecial(pfn_pte(my_zero_pfn(address), vma-&gt;vm_page_prot));
      ...
  }
  </code></pre>
  
  <p>My question is what determines <code>vm_page_prot</code>. My guess is that <code>vm_page_prot</code> is somehow a most restrictive combination (intersection) of all page permissions within the VM region, whereas <code>vm_flags</code> actually describes the true intentions of how the memory should act.</p>
  
  <p>Does anyone have any good articles on what the exact purposes/differences of the two fields are?</p>