From patchwork Tue Aug 24 16:31:41 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Luck X-Patchwork-Id: 127301 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o7OGWTh3002995 for ; Tue, 24 Aug 2010 16:32:29 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755679Ab0HXQbr (ORCPT ); Tue, 24 Aug 2010 12:31:47 -0400 Received: from mga09.intel.com ([134.134.136.24]:65475 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755636Ab0HXQbm (ORCPT ); Tue, 24 Aug 2010 12:31:42 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 24 Aug 2010 09:31:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.56,263,1280732400"; d="scan'208";a="650779377" Received: from agluck-desktop.sc.intel.com ([10.3.52.238]) by orsmga001.jf.intel.com with SMTP; 24 Aug 2010 09:31:41 -0700 From: "Luck, Tony" To: "Linus Torvalds" Cc: linux-kernel@vger.kernel.org, linux-parisc@vger.kernel.org, linux-ia64@vger.kernel.org Subject: [PATCH] guard page for stacks that grow upwards Date: Tue, 24 Aug 2010 09:31:41 -0700 Message-Id: <4c73f3ed34663af90@agluck-desktop.sc.intel.com> Sender: linux-parisc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-parisc@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 24 Aug 2010 16:32:29 +0000 (UTC) diff --git a/include/linux/mm.h b/include/linux/mm.h index 709f672..089d135 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1330,7 +1330,7 @@ unsigned long ra_submit(struct file_ra_state *ra, /* Do stack extension */ extern int expand_stack(struct vm_area_struct *vma, unsigned long address); -#ifdef CONFIG_IA64 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64) extern int expand_upwards(struct vm_area_struct *vma, unsigned long address); #endif extern int expand_stack_downwards(struct vm_area_struct *vma, diff --git a/mm/memory.c b/mm/memory.c index 2ed2267..5127b1c 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2760,29 +2760,43 @@ 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) { - struct vm_area_struct *prev = vma->vm_prev; + if (vma->vm_flags & VM_GROWSDOWN) { + address &= PAGE_MASK; + if (address == vma->vm_start) { + 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; + /* + * 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); + expand_stack(vma, address - PAGE_SIZE); + } + } +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64) + else if (vma->vm_flags & VM_GROWSUP) { + address = PAGE_ALIGN(address + 1); + if (address == vma->vm_end) { + struct vm_area_struct *next = vma->vm_next; + + /* As VM_GROWSDOWN but s/below/above/ */ + if (next && next->vm_start == address) + return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM; + + expand_upwards(vma, address); + } } +#endif return 0; } diff --git a/mm/mmap.c b/mm/mmap.c index 331e51a..6128dc8 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1716,9 +1716,6 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns * PA-RISC uses this for its stack; IA64 for its Register Backing Store. * vma is the last one with address > vma->vm_end. Have to extend vma. */ -#ifndef CONFIG_IA64 -static -#endif int expand_upwards(struct vm_area_struct *vma, unsigned long address) { int error;