diff options
Diffstat (limited to 'mm/mmap.c')
-rw-r--r-- | mm/mmap.c | 34 |
1 files changed, 29 insertions, 5 deletions
@@ -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); |