X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=mm%2Fmmap.c;h=0a89be9fbd70af385168aac7fab617a5624413ca;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=bc1c46cbaf00cf0aaa080fbc55ccf9858ac1f977;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/mm/mmap.c b/mm/mmap.c index bc1c46cba..0a89be9fb 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -318,7 +317,6 @@ static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma, if (mapping) spin_unlock(&mapping->i_mmap_lock); - mark_mm_hugetlb(mm, vma); mm->map_count++; validate_mm(mm); } @@ -363,6 +361,7 @@ void vma_adjust(struct vm_area_struct *vma, unsigned long start, { struct mm_struct *mm = vma->vm_mm; struct vm_area_struct *next = vma->vm_next; + struct vm_area_struct *importer = NULL; struct address_space *mapping = NULL; struct prio_tree_root *root = NULL; struct file *file = vma->vm_file; @@ -386,6 +385,7 @@ again: remove_next = 1 + (end > next->vm_end); */ adjust_next = (end - next->vm_start) >> PAGE_SHIFT; anon_vma = next->anon_vma; + importer = vma; } else if (end < vma->vm_end) { /* * vma shrinks, and !insert tells it's not @@ -394,6 +394,7 @@ again: remove_next = 1 + (end > next->vm_end); */ adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT); anon_vma = next->anon_vma; + importer = next; } } @@ -419,8 +420,18 @@ again: remove_next = 1 + (end > next->vm_end); */ if (vma->anon_vma) anon_vma = vma->anon_vma; - if (anon_vma) + if (anon_vma) { spin_lock(&anon_vma->lock); + /* + * Easily overlooked: when mprotect shifts the boundary, + * make sure the expanding vma has anon_vma set if the + * shrinking vma had, to cover any anon pages imported. + */ + if (importer && !importer->anon_vma) { + importer->anon_vma = anon_vma; + __anon_vma_link(importer); + } + } if (root) { flush_dcache_mmap_lock(mapping); @@ -739,6 +750,13 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, int accountable = 1; unsigned long charged = 0; + /* + * Does the application expect PROT_READ to imply PROT_EXEC: + */ + if (unlikely((prot & PROT_READ) && + (current->personality & READ_IMPLIES_EXEC))) + prot |= PROT_EXEC; + if (file) { if (is_file_hugepages(file)) accountable = 0;