summaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/process.c
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2014-01-31 22:19:52 +0100
committerHelge Deller <deller@gmx.de>2014-02-02 21:00:13 +0100
commit9dabf60dc4abe6e06bebcc2ee46b4d76ec8741f2 (patch)
tree93b98d806b1941b91ac3de04b7bd730103d3fab8 /arch/parisc/kernel/process.c
parentf5a408d53edef3af07ac7697b8bc54a755628450 (diff)
parisc: add flexible mmap memory layout support
Add support for the flexible mmap memory layout (as described in http://lwn.net/Articles/91829). This is especially very interesting on parisc since we currently only support 32bit userspace (even with a 64bit Linux kernel). Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'arch/parisc/kernel/process.c')
-rw-r--r--arch/parisc/kernel/process.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 55f92b614182..0bbbf0d3f608 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -13,7 +13,7 @@
* Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
* Copyright (C) 2001 Alan Modra <amodra at parisc-linux.org>
* Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
- * Copyright (C) 2001-2007 Helge Deller <deller at parisc-linux.org>
+ * Copyright (C) 2001-2014 Helge Deller <deller@gmx.de>
* Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
*
*
@@ -49,6 +49,7 @@
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
#include <linux/rcupdate.h>
+#include <linux/random.h>
#include <asm/io.h>
#include <asm/asm-offsets.h>
@@ -286,3 +287,21 @@ void *dereference_function_descriptor(void *ptr)
return ptr;
}
#endif
+
+static inline unsigned long brk_rnd(void)
+{
+ /* 8MB for 32bit, 1GB for 64bit */
+ if (is_32bit_task())
+ return (get_random_int() & 0x7ffUL) << PAGE_SHIFT;
+ else
+ return (get_random_int() & 0x3ffffUL) << PAGE_SHIFT;
+}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+ unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
+
+ if (ret < mm->brk)
+ return mm->brk;
+ return ret;
+}