summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAlexandre Ghiti <alex@ghiti.fr>2019-09-23 18:38:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-24 18:54:11 -0400
commit67f3977f805b34cf0e41090679800d2091d41d49 (patch)
tree890420983b1d78727127650080058e6fea253d01 /arch
parente8d54b62c55ab6201de6d195fc2c276294c1f6ae (diff)
arm64, mm: move generic mmap layout functions to mm
arm64 handles top-down mmap layout in a way that can be easily reused by other architectures, so make it available in mm. It then introduces a new config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT that can be set by other architectures to benefit from those functions. Note that this new config depends on MMU being enabled, if selected without MMU support, a warning will be thrown. Link: http://lkml.kernel.org/r/20190730055113.23635-5-alex@ghiti.fr Signed-off-by: Alexandre Ghiti <alex@ghiti.fr> Suggested-by: Christoph Hellwig <hch@infradead.org> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Kees Cook <keescook@chromium.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: James Hogan <jhogan@kernel.org> Cc: Palmer Dabbelt <palmer@sifive.com> Cc: Paul Burton <paul.burton@mips.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Russell King <linux@armlinux.org.uk> Cc: Will Deacon <will.deacon@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig10
-rw-r--r--arch/arm64/Kconfig1
-rw-r--r--arch/arm64/include/asm/processor.h2
-rw-r--r--arch/arm64/mm/mmap.c76
4 files changed, 11 insertions, 78 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 0fcf8ec1e098..dfce421b8e8a 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -706,6 +706,16 @@ config HAVE_ARCH_COMPAT_MMAP_BASES
706 and vice-versa 32-bit applications to call 64-bit mmap(). 706 and vice-versa 32-bit applications to call 64-bit mmap().
707 Required for applications doing different bitness syscalls. 707 Required for applications doing different bitness syscalls.
708 708
709# This allows to use a set of generic functions to determine mmap base
710# address by giving priority to top-down scheme only if the process
711# is not in legacy mode (compat task, unlimited stack size or
712# sysctl_legacy_va_layout).
713# Architecture that selects this option can provide its own version of:
714# - STACK_RND_MASK
715config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
716 bool
717 depends on MMU
718
709config HAVE_COPY_THREAD_TLS 719config HAVE_COPY_THREAD_TLS
710 bool 720 bool
711 help 721 help
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 37c610963eee..2d4b7044063c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -71,6 +71,7 @@ config ARM64
71 select ARCH_SUPPORTS_INT128 if GCC_VERSION >= 50000 || CC_IS_CLANG 71 select ARCH_SUPPORTS_INT128 if GCC_VERSION >= 50000 || CC_IS_CLANG
72 select ARCH_SUPPORTS_NUMA_BALANCING 72 select ARCH_SUPPORTS_NUMA_BALANCING
73 select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT 73 select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
74 select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
74 select ARCH_WANT_FRAME_POINTERS 75 select ARCH_WANT_FRAME_POINTERS
75 select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36) 76 select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
76 select ARCH_HAS_UBSAN_SANITIZE_ALL 77 select ARCH_HAS_UBSAN_SANITIZE_ALL
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index c67848c55009..5623685c7d13 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -280,8 +280,6 @@ static inline void spin_lock_prefetch(const void *ptr)
280 "nop") : : "p" (ptr)); 280 "nop") : : "p" (ptr));
281} 281}
282 282
283#define HAVE_ARCH_PICK_MMAP_LAYOUT
284
285extern unsigned long __ro_after_init signal_minsigstksz; /* sigframe size */ 283extern unsigned long __ro_after_init signal_minsigstksz; /* sigframe size */
286extern void __init minsigstksz_setup(void); 284extern void __init minsigstksz_setup(void);
287 285
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index e4acaead67de..3028bacbc4e9 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -21,82 +21,6 @@
21#include <asm/cputype.h> 21#include <asm/cputype.h>
22 22
23/* 23/*
24 * Leave enough space between the mmap area and the stack to honour ulimit in
25 * the face of randomisation.
26 */
27#define MIN_GAP (SZ_128M)
28#define MAX_GAP (STACK_TOP/6*5)
29
30static int mmap_is_legacy(struct rlimit *rlim_stack)
31{
32 if (current->personality & ADDR_COMPAT_LAYOUT)
33 return 1;
34
35 if (rlim_stack->rlim_cur == RLIM_INFINITY)
36 return 1;
37
38 return sysctl_legacy_va_layout;
39}
40
41unsigned long arch_mmap_rnd(void)
42{
43 unsigned long rnd;
44
45#ifdef CONFIG_COMPAT
46 if (is_compat_task())
47 rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
48 else
49#endif
50 rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
51 return rnd << PAGE_SHIFT;
52}
53
54static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
55{
56 unsigned long gap = rlim_stack->rlim_cur;
57 unsigned long pad = stack_guard_gap;
58
59 /* Account for stack randomization if necessary */
60 if (current->flags & PF_RANDOMIZE)
61 pad += (STACK_RND_MASK << PAGE_SHIFT);
62
63 /* Values close to RLIM_INFINITY can overflow. */
64 if (gap + pad > gap)
65 gap += pad;
66
67 if (gap < MIN_GAP)
68 gap = MIN_GAP;
69 else if (gap > MAX_GAP)
70 gap = MAX_GAP;
71
72 return PAGE_ALIGN(STACK_TOP - gap - rnd);
73}
74
75/*
76 * This function, called very early during the creation of a new process VM
77 * image, sets up which VM layout function to use:
78 */
79void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
80{
81 unsigned long random_factor = 0UL;
82
83 if (current->flags & PF_RANDOMIZE)
84 random_factor = arch_mmap_rnd();
85
86 /*
87 * Fall back to the standard layout if the personality bit is set, or
88 * if the expected stack growth is unlimited:
89 */
90 if (mmap_is_legacy(rlim_stack)) {
91 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
92 mm->get_unmapped_area = arch_get_unmapped_area;
93 } else {
94 mm->mmap_base = mmap_base(random_factor, rlim_stack);
95 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
96 }
97}
98
99/*
100 * You really shouldn't be using read() or write() on /dev/mem. This might go 24 * You really shouldn't be using read() or write() on /dev/mem. This might go
101 * away in the future. 25 * away in the future.
102 */ 26 */