diff options
Diffstat (limited to 'mm/memory.c')
| -rw-r--r-- | mm/memory.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/mm/memory.c b/mm/memory.c index 2ed2267439df..6b2ab1051851 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -2760,11 +2760,9 @@ out_release: | |||
| 2760 | } | 2760 | } |
| 2761 | 2761 | ||
| 2762 | /* | 2762 | /* |
| 2763 | * This is like a special single-page "expand_downwards()", | 2763 | * This is like a special single-page "expand_{down|up}wards()", |
| 2764 | * except we must first make sure that 'address-PAGE_SIZE' | 2764 | * except we must first make sure that 'address{-|+}PAGE_SIZE' |
| 2765 | * doesn't hit another vma. | 2765 | * doesn't hit another vma. |
| 2766 | * | ||
| 2767 | * The "find_vma()" will do the right thing even if we wrap | ||
| 2768 | */ | 2766 | */ |
| 2769 | static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) | 2767 | static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) |
| 2770 | { | 2768 | { |
| @@ -2783,6 +2781,15 @@ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned lo | |||
| 2783 | 2781 | ||
| 2784 | expand_stack(vma, address - PAGE_SIZE); | 2782 | expand_stack(vma, address - PAGE_SIZE); |
| 2785 | } | 2783 | } |
| 2784 | if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) { | ||
| 2785 | struct vm_area_struct *next = vma->vm_next; | ||
| 2786 | |||
| 2787 | /* As VM_GROWSDOWN but s/below/above/ */ | ||
| 2788 | if (next && next->vm_start == address + PAGE_SIZE) | ||
| 2789 | return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM; | ||
| 2790 | |||
| 2791 | expand_upwards(vma, address + PAGE_SIZE); | ||
| 2792 | } | ||
| 2786 | return 0; | 2793 | return 0; |
| 2787 | } | 2794 | } |
| 2788 | 2795 | ||
