From patchwork Fri Aug 20 17:56:47 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tony Luck X-Patchwork-Id: 120662 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 o7KHv3Ua000617 for ; Fri, 20 Aug 2010 17:57:03 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752714Ab0HTR4t (ORCPT ); Fri, 20 Aug 2010 13:56:49 -0400 Received: from mga02.intel.com ([134.134.136.20]:5563 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752432Ab0HTR4s (ORCPT ); Fri, 20 Aug 2010 13:56:48 -0400 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 20 Aug 2010 10:56:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.56,240,1280732400"; d="scan'208";a="649710727" Received: from agluck-desktop.sc.intel.com ([10.3.52.238]) by orsmga001.jf.intel.com with SMTP; 20 Aug 2010 10:56:47 -0700 From: "Luck, Tony" To: linux-kernel@vger.kernel.org Cc: linux-ia64@vger.kernel.org, linux-parisc@vger.kernel.org, "Kyle McMartin" , "Helge Deller" , "James E.J. Bottomley" , "Matthew Wilcox" Subject: [RFC - PATCH] leave guard page for upwardly growing stacks too Date: Fri, 20 Aug 2010 10:56:47 -0700 Message-Id: <4c6ec1df290705bb68@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]); Fri, 20 Aug 2010 17:57:03 +0000 (UTC) diff --git a/mm/memory.c b/mm/memory.c index b6e5fd2..9dcef72 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2760,21 +2760,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 *v; + + if (vma->vm_flags & VM_GROWSDOWN) { + address &= PAGE_MASK; + if (address == vma->vm_start) { + address -= PAGE_SIZE; + if (find_vma(vma->vm_mm, address) != vma) + return -ENOMEM; - expand_stack(vma, address); + expand_stack(vma, address); + } + } else if (vma->vm_flags & VM_GROWSUP) { + address = PAGE_ALIGN(address + 1); + if (address == vma->vm_end) { + address += PAGE_SIZE; + if ((v = find_vma(vma->vm_mm, address)) && + v->vm_start <= address) { + return -ENOMEM; + } + expand_upwards(vma, address); + } } return 0; }