Ed L Cashin <ecashin@uga.edu> writes: > Hi. In mm/mprotect.c, there's a function, change_pte_range, that > adjusts the protection settings in a range of ptes. > > I know that when a page is set up for copy on write, the pte is set > such that a write will result in a page fault. A cow page pte is set > for write protection, and the vma is marked as writable, so > vma->vm_flags & VM_WRITE would be true. > > That's why I expected to see some sort of special case for this > situation in change_pte_range. I thought there would be something > like the code below: > > pte_t new_pte = pte_modify(entry, newprot); > > if (vma->vm_flags & VM_WRITE && !pte_write(*pte)) > new_pte = pte_wrprotect(new_pte); /* for cow */ > > .. otherwise it seems like you could ruin the cow settings when > adjusting page protections. Why isn't that needed? Since nobody responded, I figured I'd share what I found: in mprotect Linux appears to *always* set things up as copy on write when (vma->vm_flags & VM_SHARED) is false and (vma->vm_flags & VM_WRITE) is true. It happens when the protections used for the pte are looked up in the protection_map, defined in mm/mmap.c. The index into the protection_map is vm_flags & 0xf, and if the VM_SHARED bit (0x8) isn't set, then you get one of the __PNNN settings. None of those page protections have the _PAGE_RW bit set. So if you mprotect an anonymous, private page of memory to PROT_NONE and then back to PROT_READ|PROT_WRITE|PROT_EXEC, you'll get a minor page fault when you try to write to it. -- --Ed L Cashin | PGP public key: ecashin@uga.edu | http://noserose.net/e/pgp/ -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/