linux/arch/tile/mm/mmap.c
<<
>>
Prefs
   1/*
   2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
   3 *
   4 *   This program is free software; you can redistribute it and/or
   5 *   modify it under the terms of the GNU General Public License
   6 *   as published by the Free Software Foundation, version 2.
   7 *
   8 *   This program is distributed in the hope that it will be useful, but
   9 *   WITHOUT ANY WARRANTY; without even the implied warranty of
  10 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11 *   NON INFRINGEMENT.  See the GNU General Public License for
  12 *   more details.
  13 *
  14 * Taken from the i386 architecture and simplified.
  15 */
  16
  17#include <linux/mm.h>
  18#include <linux/random.h>
  19#include <linux/limits.h>
  20#include <linux/sched/signal.h>
  21#include <linux/sched/mm.h>
  22#include <linux/mman.h>
  23#include <linux/compat.h>
  24
  25/*
  26 * Top of mmap area (just below the process stack).
  27 *
  28 * Leave an at least ~128 MB hole.
  29 */
  30#define MIN_GAP (128*1024*1024)
  31#define MAX_GAP (TASK_SIZE/6*5)
  32
  33static inline unsigned long mmap_base(struct mm_struct *mm)
  34{
  35        unsigned long gap = rlimit(RLIMIT_STACK);
  36        unsigned long random_factor = 0;
  37
  38        if (current->flags & PF_RANDOMIZE)
  39                random_factor = get_random_int() % (1024*1024);
  40
  41        if (gap < MIN_GAP)
  42                gap = MIN_GAP;
  43        else if (gap > MAX_GAP)
  44                gap = MAX_GAP;
  45
  46        return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
  47}
  48
  49/*
  50 * This function, called very early during the creation of a new
  51 * process VM image, sets up which VM layout function to use:
  52 */
  53void arch_pick_mmap_layout(struct mm_struct *mm)
  54{
  55#if !defined(__tilegx__)
  56        int is_32bit = 1;
  57#elif defined(CONFIG_COMPAT)
  58        int is_32bit = is_compat_task();
  59#else
  60        int is_32bit = 0;
  61#endif
  62        unsigned long random_factor = 0UL;
  63
  64        /*
  65         *  8 bits of randomness in 32bit mmaps, 24 address space bits
  66         * 12 bits of randomness in 64bit mmaps, 28 address space bits
  67         */
  68        if (current->flags & PF_RANDOMIZE) {
  69                if (is_32bit)
  70                        random_factor = get_random_int() % (1<<8);
  71                else
  72                        random_factor = get_random_int() % (1<<12);
  73
  74                random_factor <<= PAGE_SHIFT;
  75        }
  76
  77        /*
  78         * Use standard layout if the expected stack growth is unlimited
  79         * or we are running native 64 bits.
  80         */
  81        if (rlimit(RLIMIT_STACK) == RLIM_INFINITY) {
  82                mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
  83                mm->get_unmapped_area = arch_get_unmapped_area;
  84        } else {
  85                mm->mmap_base = mmap_base(mm);
  86                mm->get_unmapped_area = arch_get_unmapped_area_topdown;
  87        }
  88}
  89
  90unsigned long arch_randomize_brk(struct mm_struct *mm)
  91{
  92        return randomize_page(mm->brk, 0x02000000);
  93}
  94