diff options
author | Alexandre Ghiti <alex@ghiti.fr> | 2019-09-23 18:38:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-24 18:54:11 -0400 |
commit | 67f3977f805b34cf0e41090679800d2091d41d49 (patch) | |
tree | 890420983b1d78727127650080058e6fea253d01 /arch | |
parent | e8d54b62c55ab6201de6d195fc2c276294c1f6ae (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/Kconfig | 10 | ||||
-rw-r--r-- | arch/arm64/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/arm64/mm/mmap.c | 76 |
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 | ||
715 | config ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT | ||
716 | bool | ||
717 | depends on MMU | ||
718 | |||
709 | config HAVE_COPY_THREAD_TLS | 719 | config 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 | |||
285 | extern unsigned long __ro_after_init signal_minsigstksz; /* sigframe size */ | 283 | extern unsigned long __ro_after_init signal_minsigstksz; /* sigframe size */ |
286 | extern void __init minsigstksz_setup(void); | 284 | extern 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 | |||
30 | static 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 | |||
41 | unsigned 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 | |||
54 | static 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 | */ | ||
79 | void 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 | */ |