1 /* 2 * linux/arch/s390/mm/mmap.c 3 * 4 * flexible mmap layout support 5 * 6 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 7 * All Rights Reserved. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 * 24 * Started by Ingo Molnar <mingo@elte.hu> 25 */ 26 27 #include <linux/personality.h> 28 #include <linux/mm.h> 29 #include <linux/module.h> 30 31 /* 32 * Top of mmap area (just below the process stack). 33 * 34 * Leave an at least ~128 MB hole. 35 */ 36 #define MIN_GAP (128*1024*1024) 37 #define MAX_GAP (TASK_SIZE/6*5) 38 39 static inline unsigned long mmap_base(void) 40 { 41 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; 42 43 if (gap < MIN_GAP) 44 gap = MIN_GAP; 45 else if (gap > MAX_GAP) 46 gap = MAX_GAP; 47 48 return TASK_SIZE - (gap & PAGE_MASK); 49 } 50 51 static inline int mmap_is_legacy(void) 52 { 53 #ifdef CONFIG_ARCH_S390X 54 /* 55 * Force standard allocation for 64 bit programs. 56 */ 57 if (!test_thread_flag(TIF_31BIT)) 58 return 1; 59 #endif 60 return sysctl_legacy_va_layout || 61 (current->personality & ADDR_COMPAT_LAYOUT) || 62 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY; 63 } 64 65 /* 66 * This function, called very early during the creation of a new 67 * process VM image, sets up which VM layout function to use: 68 */ 69 void arch_pick_mmap_layout(struct mm_struct *mm) 70 { 71 /* 72 * Fall back to the standard layout if the personality 73 * bit is set, or if the expected stack growth is unlimited: 74 */ 75 if (mmap_is_legacy()) { 76 mm->mmap_base = TASK_UNMAPPED_BASE; 77 mm->get_unmapped_area = arch_get_unmapped_area; 78 mm->unmap_area = arch_unmap_area; 79 } else { 80 mm->mmap_base = mmap_base(); 81 mm->get_unmapped_area = arch_get_unmapped_area_topdown; 82 mm->unmap_area = arch_unmap_area_topdown; 83 } 84 } 85 EXPORT_SYMBOL_GPL(arch_pick_mmap_layout); 86 87