summaryrefslogtreecommitdiffstats
path: root/mm/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 2f2415a7a688..76d1ec29149b 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2664,12 +2664,29 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
2664 if (!vma || !(vma->vm_flags & VM_SHARED)) 2664 if (!vma || !(vma->vm_flags & VM_SHARED))
2665 goto out; 2665 goto out;
2666 2666
2667 if (start < vma->vm_start || start + size > vma->vm_end) 2667 if (start < vma->vm_start)
2668 goto out; 2668 goto out;
2669 2669
2670 if (pgoff == linear_page_index(vma, start)) { 2670 if (start + size > vma->vm_end) {
2671 ret = 0; 2671 struct vm_area_struct *next;
2672 goto out; 2672
2673 for (next = vma->vm_next; next; next = next->vm_next) {
2674 /* hole between vmas ? */
2675 if (next->vm_start != next->vm_prev->vm_end)
2676 goto out;
2677
2678 if (next->vm_file != vma->vm_file)
2679 goto out;
2680
2681 if (next->vm_flags != vma->vm_flags)
2682 goto out;
2683
2684 if (start + size <= next->vm_end)
2685 break;
2686 }
2687
2688 if (!next)
2689 goto out;
2673 } 2690 }
2674 2691
2675 prot |= vma->vm_flags & VM_READ ? PROT_READ : 0; 2692 prot |= vma->vm_flags & VM_READ ? PROT_READ : 0;
@@ -2679,9 +2696,16 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
2679 flags &= MAP_NONBLOCK; 2696 flags &= MAP_NONBLOCK;
2680 flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE; 2697 flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE;
2681 if (vma->vm_flags & VM_LOCKED) { 2698 if (vma->vm_flags & VM_LOCKED) {
2699 struct vm_area_struct *tmp;
2682 flags |= MAP_LOCKED; 2700 flags |= MAP_LOCKED;
2701
2683 /* drop PG_Mlocked flag for over-mapped range */ 2702 /* drop PG_Mlocked flag for over-mapped range */
2684 munlock_vma_pages_range(vma, start, start + size); 2703 for (tmp = vma; tmp->vm_start >= start + size;
2704 tmp = tmp->vm_next) {
2705 munlock_vma_pages_range(tmp,
2706 max(tmp->vm_start, start),
2707 min(tmp->vm_end, start + size));
2708 }
2685 } 2709 }
2686 2710
2687 file = get_file(vma->vm_file); 2711 file = get_file(vma->vm_file);