diff options
Diffstat (limited to 'mm/mremap.c')
-rw-r--r-- | mm/mremap.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/mm/mremap.c b/mm/mremap.c index 90e422c9f410..9d0753983dcb 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -27,6 +27,10 @@ | |||
27 | 27 | ||
28 | #include "internal.h" | 28 | #include "internal.h" |
29 | 29 | ||
30 | #ifndef arch_mmap_check | ||
31 | #define arch_mmap_check(addr, len, flags) (0) | ||
32 | #endif | ||
33 | |||
30 | static pmd_t *get_old_pmd(struct mm_struct *mm, unsigned long addr) | 34 | static pmd_t *get_old_pmd(struct mm_struct *mm, unsigned long addr) |
31 | { | 35 | { |
32 | pgd_t *pgd; | 36 | pgd_t *pgd; |
@@ -368,12 +372,17 @@ out: | |||
368 | 372 | ||
369 | static int vma_expandable(struct vm_area_struct *vma, unsigned long delta) | 373 | static int vma_expandable(struct vm_area_struct *vma, unsigned long delta) |
370 | { | 374 | { |
375 | unsigned long end = vma->vm_end + delta; | ||
371 | unsigned long max_addr = TASK_SIZE; | 376 | unsigned long max_addr = TASK_SIZE; |
372 | if (vma->vm_next) | 377 | if (vma->vm_next) |
373 | max_addr = vma->vm_next->vm_start; | 378 | max_addr = vma->vm_next->vm_start; |
374 | if (max_addr - vma->vm_end < delta) | 379 | if (max_addr < end || end < vma->vm_end) |
380 | return 0; | ||
381 | if (arch_mmap_check(vma->vm_start, end - vma->vm_start, MAP_FIXED)) | ||
382 | return 0; | ||
383 | if (get_unmapped_area(NULL, vma->vm_start, end - vma->vm_start, | ||
384 | 0, MAP_FIXED) & ~PAGE_MASK) | ||
375 | return 0; | 385 | return 0; |
376 | /* we need to do arch-specific checks here */ | ||
377 | return 1; | 386 | return 1; |
378 | } | 387 | } |
379 | 388 | ||