aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/mm/memory.c b/mm/memory.c
index b6e5fd23cc5..6b2ab105185 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2760,21 +2760,35 @@ 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 */
2769static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) 2767static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address)
2770{ 2768{
2771 address &= PAGE_MASK; 2769 address &= PAGE_MASK;
2772 if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) { 2770 if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
2773 address -= PAGE_SIZE; 2771 struct vm_area_struct *prev = vma->vm_prev;
2774 if (find_vma(vma->vm_mm, address) != vma) 2772
2775 return -ENOMEM; 2773 /*
2774 * Is there a mapping abutting this one below?
2775 *
2776 * That's only ok if it's the same stack mapping
2777 * that has gotten split..
2778 */
2779 if (prev && prev->vm_end == address)
2780 return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
2781
2782 expand_stack(vma, address - PAGE_SIZE);
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;
2776 2790
2777 expand_stack(vma, address); 2791 expand_upwards(vma, address + PAGE_SIZE);
2778 } 2792 }
2779 return 0; 2793 return 0;
2780} 2794}