X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=mm%2Fmemory.c;h=53c1da0d04a68d02bd1fd9eba8c925ceda59fec8;hb=3332f84e0b969bd699d783e00e72a9110929eeed;hp=babb991fb02ba69bdfec04347a14dc2e81d9a836;hpb=058daedc8311ab42702dfe29d3ff16dff7e7eaf8;p=firefly-linux-kernel-4.4.55.git diff --git a/mm/memory.c b/mm/memory.c index babb991fb02b..53c1da0d04a6 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2630,21 +2630,35 @@ out_release: } /* - * This is like a special single-page "expand_downwards()", - * except we must first make sure that 'address-PAGE_SIZE' + * This is like a special single-page "expand_{down|up}wards()", + * except we must first make sure that 'address{-|+}PAGE_SIZE' * doesn't hit another vma. - * - * The "find_vma()" will do the right thing even if we wrap */ static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) { address &= PAGE_MASK; if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) { - address -= PAGE_SIZE; - if (find_vma(vma->vm_mm, address) != vma) - return -ENOMEM; + struct vm_area_struct *prev = vma->vm_prev; + + /* + * Is there a mapping abutting this one below? + * + * That's only ok if it's the same stack mapping + * that has gotten split.. + */ + if (prev && prev->vm_end == address) + return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM; + + expand_stack(vma, address - PAGE_SIZE); + } + if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) { + struct vm_area_struct *next = vma->vm_next; + + /* As VM_GROWSDOWN but s/below/above/ */ + if (next && next->vm_start == address + PAGE_SIZE) + return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM; - expand_stack(vma, address); + expand_upwards(vma, address + PAGE_SIZE); } return 0; }