* [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm
2019-03-22 7:42 [PATCH 0/4] Provide generic top-down mmap layout functions Alexandre Ghiti
@ 2019-03-22 7:42 ` Alexandre Ghiti
2019-03-22 13:21 ` Christoph Hellwig
2019-03-22 7:42 ` [PATCH 2/4] arm: Use generic mmap top-down layout Alexandre Ghiti
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Alexandre Ghiti @ 2019-03-22 7:42 UTC (permalink / raw)
To: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
linux-fsdevel, linux-mm
Cc: Alexandre Ghiti
arm64 handles top-down mmap layout in a way that can be easily reused
by other architectures, so make it available in mm.
This commit also takes the opportunity to:
- make use of is_compat_task instead of specific arm64 test
test_thread_flag(TIF_32BIT), which allows more genericity and is
equivalent.
- fix the case where stack randomization should not be taken into
account.
It then introduces a new define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
that can be defined by other architectures to benefit from those functions.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
arch/arm64/include/asm/processor.h | 2 +-
arch/arm64/mm/mmap.c | 72 ----------------------
fs/binfmt_elf.c | 20 ------
include/linux/mm.h | 2 +
kernel/sysctl.c | 6 +-
mm/util.c | 99 +++++++++++++++++++++++++++++-
6 files changed, 105 insertions(+), 96 deletions(-)
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 5d9ce62bdebd..2358707c31ff 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -274,7 +274,7 @@ static inline void spin_lock_prefetch(const void *ptr)
"nop") : : "p" (ptr));
}
-#define HAVE_ARCH_PICK_MMAP_LAYOUT
+#define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
#endif
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 842c8a5fcd53..c74224421216 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -31,78 +31,6 @@
#include <asm/cputype.h>
-/*
- * Leave enough space between the mmap area and the stack to honour ulimit in
- * the face of randomisation.
- */
-#define MIN_GAP (SZ_128M)
-#define MAX_GAP (STACK_TOP/6*5)
-
-static int mmap_is_legacy(struct rlimit *rlim_stack)
-{
- if (current->personality & ADDR_COMPAT_LAYOUT)
- return 1;
-
- if (rlim_stack->rlim_cur == RLIM_INFINITY)
- return 1;
-
- return sysctl_legacy_va_layout;
-}
-
-unsigned long arch_mmap_rnd(void)
-{
- unsigned long rnd;
-
-#ifdef CONFIG_COMPAT
- if (test_thread_flag(TIF_32BIT))
- rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
- else
-#endif
- rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
- return rnd << PAGE_SHIFT;
-}
-
-static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
-{
- unsigned long gap = rlim_stack->rlim_cur;
- unsigned long pad = (STACK_RND_MASK << PAGE_SHIFT) + stack_guard_gap;
-
- /* Values close to RLIM_INFINITY can overflow. */
- if (gap + pad > gap)
- gap += pad;
-
- if (gap < MIN_GAP)
- gap = MIN_GAP;
- else if (gap > MAX_GAP)
- gap = MAX_GAP;
-
- return PAGE_ALIGN(STACK_TOP - gap - rnd);
-}
-
-/*
- * This function, called very early during the creation of a new process VM
- * image, sets up which VM layout function to use:
- */
-void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
-{
- unsigned long random_factor = 0UL;
-
- if (current->flags & PF_RANDOMIZE)
- random_factor = arch_mmap_rnd();
-
- /*
- * Fall back to the standard layout if the personality bit is set, or
- * if the expected stack growth is unlimited:
- */
- if (mmap_is_legacy(rlim_stack)) {
- mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
- mm->get_unmapped_area = arch_get_unmapped_area;
- } else {
- mm->mmap_base = mmap_base(random_factor, rlim_stack);
- mm->get_unmapped_area = arch_get_unmapped_area_topdown;
- }
-}
-
/*
* You really shouldn't be using read() or write() on /dev/mem. This might go
* away in the future.
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 7d09d125f148..045f3b29d264 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -662,26 +662,6 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
* libraries. There is no binary dependent code anywhere else.
*/
-#ifndef STACK_RND_MASK
-#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
-#endif
-
-static unsigned long randomize_stack_top(unsigned long stack_top)
-{
- unsigned long random_variable = 0;
-
- if (current->flags & PF_RANDOMIZE) {
- random_variable = get_random_long();
- random_variable &= STACK_RND_MASK;
- random_variable <<= PAGE_SHIFT;
- }
-#ifdef CONFIG_STACK_GROWSUP
- return PAGE_ALIGN(stack_top) + random_variable;
-#else
- return PAGE_ALIGN(stack_top) - random_variable;
-#endif
-}
-
static int load_elf_binary(struct linux_binprm *bprm)
{
struct file *interpreter = NULL; /* to shut gcc up */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 76769749b5a5..087824a5059f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2312,6 +2312,8 @@ extern int install_special_mapping(struct mm_struct *mm,
unsigned long addr, unsigned long len,
unsigned long flags, struct page **pages);
+unsigned long randomize_stack_top(unsigned long stack_top);
+
extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
extern unsigned long mmap_region(struct file *file, unsigned long addr,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index e5da394d1ca3..ac388f8ccbe4 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -269,7 +269,8 @@ extern struct ctl_table epoll_table[];
extern struct ctl_table firmware_config_table[];
#endif
-#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
+#if defined(HAVE_ARCH_PICK_MMAP_LAYOUT) || \
+ defined(ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT)
int sysctl_legacy_va_layout;
#endif
@@ -1564,7 +1565,8 @@ static struct ctl_table vm_table[] = {
.proc_handler = proc_dointvec,
.extra1 = &zero,
},
-#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
+#if defined(HAVE_ARCH_PICK_MMAP_LAYOUT) || \
+ defined(ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT)
{
.procname = "legacy_va_layout",
.data = &sysctl_legacy_va_layout,
diff --git a/mm/util.c b/mm/util.c
index d559bde497a9..5a0d4b1e17d9 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -14,6 +14,13 @@
#include <linux/hugetlb.h>
#include <linux/vmalloc.h>
#include <linux/userfaultfd_k.h>
+#include <linux/elf.h>
+#include <linux/elf-randomize.h>
+#include <linux/personality.h>
+#include <linux/random.h>
+#include <linux/processor.h>
+#include <linux/sizes.h>
+#include <linux/compat.h>
#include <linux/uaccess.h>
@@ -291,13 +298,103 @@ int vma_is_stack_for_current(struct vm_area_struct *vma)
return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t));
}
-#if defined(CONFIG_MMU) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
+#ifndef STACK_RND_MASK
+#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
+#endif
+
+unsigned long randomize_stack_top(unsigned long stack_top)
+{
+ unsigned long random_variable = 0;
+
+ if (current->flags & PF_RANDOMIZE) {
+ random_variable = get_random_long();
+ random_variable &= STACK_RND_MASK;
+ random_variable <<= PAGE_SHIFT;
+ }
+#ifdef CONFIG_STACK_GROWSUP
+ return PAGE_ALIGN(stack_top) + random_variable;
+#else
+ return PAGE_ALIGN(stack_top) - random_variable;
+#endif
+}
+
+#ifdef CONFIG_MMU
+#ifdef ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
+
+#ifdef CONFIG_ARCH_HAS_ELF_RANDOMIZE
+unsigned long arch_mmap_rnd(void)
+{
+ unsigned long rnd;
+
+#ifdef CONFIG_COMPAT
+ if (is_compat_task())
+ rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
+ else
+#endif
+ rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
+
+ return rnd << PAGE_SHIFT;
+}
+#endif
+
+static int mmap_is_legacy(struct rlimit *rlim_stack)
+{
+ if (current->personality & ADDR_COMPAT_LAYOUT)
+ return 1;
+
+ if (rlim_stack->rlim_cur == RLIM_INFINITY)
+ return 1;
+
+ return sysctl_legacy_va_layout;
+}
+
+#define MIN_GAP (SZ_128M)
+#define MAX_GAP (STACK_TOP / 6 * 5)
+
+static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
+{
+ unsigned long gap = rlim_stack->rlim_cur;
+ unsigned long pad = stack_guard_gap;
+
+ /* Account for stack randomization if necessary */
+ if (current->flags & PF_RANDOMIZE)
+ pad += (STACK_RND_MASK << PAGE_SHIFT);
+
+ /* Values close to RLIM_INFINITY can overflow. */
+ if (gap + pad > gap)
+ gap += pad;
+
+ if (gap < MIN_GAP)
+ gap = MIN_GAP;
+ else if (gap > MAX_GAP)
+ gap = MAX_GAP;
+
+ return PAGE_ALIGN(STACK_TOP - gap - rnd);
+}
+
+void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
+{
+ unsigned long random_factor = 0UL;
+
+ if (current->flags & PF_RANDOMIZE)
+ random_factor = arch_mmap_rnd();
+
+ if (mmap_is_legacy(rlim_stack)) {
+ mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
+ mm->get_unmapped_area = arch_get_unmapped_area;
+ } else {
+ mm->mmap_base = mmap_base(random_factor, rlim_stack);
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+ }
+}
+#elif !defined(HAVE_ARCH_PICK_MMAP_LAYOUT)
void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
{
mm->mmap_base = TASK_UNMAPPED_BASE;
mm->get_unmapped_area = arch_get_unmapped_area;
}
#endif
+#endif /* CONFIG_MMU */
/*
* Like get_user_pages_fast() except its IRQ-safe in that it won't fall
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm
2019-03-22 7:42 ` [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm Alexandre Ghiti
@ 2019-03-22 13:21 ` Christoph Hellwig
2019-03-23 8:18 ` Alex Ghiti
0 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2019-03-22 13:21 UTC (permalink / raw)
To: Alexandre Ghiti
Cc: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
linux-fsdevel, linux-mm
> It then introduces a new define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
> that can be defined by other architectures to benefit from those functions.
Can you make this a Kconfig option defined in arch/Kconfig or mm/Kconfig
and selected by the architectures?
> -#ifndef STACK_RND_MASK
> -#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
> -#endif
> -
> -static unsigned long randomize_stack_top(unsigned long stack_top)
> -{
> - unsigned long random_variable = 0;
> -
> - if (current->flags & PF_RANDOMIZE) {
> - random_variable = get_random_long();
> - random_variable &= STACK_RND_MASK;
> - random_variable <<= PAGE_SHIFT;
> - }
> -#ifdef CONFIG_STACK_GROWSUP
> - return PAGE_ALIGN(stack_top) + random_variable;
> -#else
> - return PAGE_ALIGN(stack_top) - random_variable;
> -#endif
> -}
> -
Maybe the move of this function can be split into another prep patch,
as it is only very lightly related?
> +#if defined(HAVE_ARCH_PICK_MMAP_LAYOUT) || \
> + defined(ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT)
Not sure if it is wrіtten down somehwere or just convention, but I
general see cpp defined statements aligned with spaces to the
one on the previous line.
Except for these nitpicks this looks very nice to me, thanks for doing
this work!
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm
2019-03-22 13:21 ` Christoph Hellwig
@ 2019-03-23 8:18 ` Alex Ghiti
0 siblings, 0 replies; 9+ messages in thread
From: Alex Ghiti @ 2019-03-23 8:18 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Russell King, Catalin Marinas, Will Deacon, Ralf Baechle,
Paul Burton, James Hogan, Palmer Dabbelt, Albert Ou,
Alexander Viro, Luis Chamberlain, Kees Cook, linux-arm-kernel,
linux-kernel, linux-mips, linux-riscv, linux-fsdevel, linux-mm
On 3/22/19 9:21 AM, Christoph Hellwig wrote:
>> It then introduces a new define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
>> that can be defined by other architectures to benefit from those functions.
> Can you make this a Kconfig option defined in arch/Kconfig or mm/Kconfig
> and selected by the architectures?
Yes, I will do.
>> -#ifndef STACK_RND_MASK
>> -#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
>> -#endif
>> -
>> -static unsigned long randomize_stack_top(unsigned long stack_top)
>> -{
>> - unsigned long random_variable = 0;
>> -
>> - if (current->flags & PF_RANDOMIZE) {
>> - random_variable = get_random_long();
>> - random_variable &= STACK_RND_MASK;
>> - random_variable <<= PAGE_SHIFT;
>> - }
>> -#ifdef CONFIG_STACK_GROWSUP
>> - return PAGE_ALIGN(stack_top) + random_variable;
>> -#else
>> - return PAGE_ALIGN(stack_top) - random_variable;
>> -#endif
>> -}
>> -
> Maybe the move of this function can be split into another prep patch,
> as it is only very lightly related?
>
>
Ok, that makes sense.
>> +#if defined(HAVE_ARCH_PICK_MMAP_LAYOUT) || \
>> + defined(ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT)
> Not sure if it is wrіtten down somehwere or just convention, but I
> general see cpp defined statements aligned with spaces to the
> one on the previous line.
Ok, I will fix that.
> Except for these nitpicks this looks very nice to me, thanks for doing
> this work!
Thanks :)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/4] arm: Use generic mmap top-down layout
2019-03-22 7:42 [PATCH 0/4] Provide generic top-down mmap layout functions Alexandre Ghiti
2019-03-22 7:42 ` [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm Alexandre Ghiti
@ 2019-03-22 7:42 ` Alexandre Ghiti
2019-03-22 7:42 ` [PATCH 3/4] mips: " Alexandre Ghiti
2019-03-22 7:42 ` [PATCH 4/4] riscv: Make mmap allocation top-down by default Alexandre Ghiti
3 siblings, 0 replies; 9+ messages in thread
From: Alexandre Ghiti @ 2019-03-22 7:42 UTC (permalink / raw)
To: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
linux-fsdevel, linux-mm
Cc: Alexandre Ghiti
arm uses a top-down layout by default that fits the generic functions.
At the same time, this commit allows to fix the following problems:
- one uncovered and not fixed for arm here:
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1429066.html
- the use of TASK_SIZE instead of STACK_TOP in mmap_base which, when
address space of a task is 26 bits, would assign mmap base way too high.
Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
arch/arm/include/asm/processor.h | 2 +-
arch/arm/mm/mmap.c | 52 --------------------------------
2 files changed, 1 insertion(+), 53 deletions(-)
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 57fe73ea0f72..03837d325a2f 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -143,7 +143,7 @@ static inline void prefetchw(const void *ptr)
#endif
#endif
-#define HAVE_ARCH_PICK_MMAP_LAYOUT
+#define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
#endif
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index f866870db749..b8d912ac9e61 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -17,33 +17,6 @@
((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \
(((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
-/* gap between mmap and stack */
-#define MIN_GAP (128*1024*1024UL)
-#define MAX_GAP ((TASK_SIZE)/6*5)
-
-static int mmap_is_legacy(struct rlimit *rlim_stack)
-{
- if (current->personality & ADDR_COMPAT_LAYOUT)
- return 1;
-
- if (rlim_stack->rlim_cur == RLIM_INFINITY)
- return 1;
-
- return sysctl_legacy_va_layout;
-}
-
-static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
-{
- unsigned long gap = rlim_stack->rlim_cur;
-
- if (gap < MIN_GAP)
- gap = MIN_GAP;
- else if (gap > MAX_GAP)
- gap = MAX_GAP;
-
- return PAGE_ALIGN(TASK_SIZE - gap - rnd);
-}
-
/*
* We need to ensure that shared mappings are correctly aligned to
* avoid aliasing issues with VIPT caches. We need to ensure that
@@ -171,31 +144,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr;
}
-unsigned long arch_mmap_rnd(void)
-{
- unsigned long rnd;
-
- rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
-
- return rnd << PAGE_SHIFT;
-}
-
-void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
-{
- unsigned long random_factor = 0UL;
-
- if (current->flags & PF_RANDOMIZE)
- random_factor = arch_mmap_rnd();
-
- if (mmap_is_legacy(rlim_stack)) {
- mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
- mm->get_unmapped_area = arch_get_unmapped_area;
- } else {
- mm->mmap_base = mmap_base(random_factor, rlim_stack);
- mm->get_unmapped_area = arch_get_unmapped_area_topdown;
- }
-}
-
/*
* You really shouldn't be using read() or write() on /dev/mem. This
* might go away in the future.
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/4] mips: Use generic mmap top-down layout
2019-03-22 7:42 [PATCH 0/4] Provide generic top-down mmap layout functions Alexandre Ghiti
2019-03-22 7:42 ` [PATCH 1/4] arm64, mm: Move generic mmap layout functions to mm Alexandre Ghiti
2019-03-22 7:42 ` [PATCH 2/4] arm: Use generic mmap top-down layout Alexandre Ghiti
@ 2019-03-22 7:42 ` Alexandre Ghiti
2019-03-22 7:42 ` [PATCH 4/4] riscv: Make mmap allocation top-down by default Alexandre Ghiti
3 siblings, 0 replies; 9+ messages in thread
From: Alexandre Ghiti @ 2019-03-22 7:42 UTC (permalink / raw)
To: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
linux-fsdevel, linux-mm
Cc: Alexandre Ghiti
mips uses a top-down layout by default that fits the generic functions.
At the same time, this commit allows to fix problem uncovered
and not fixed for mips here:
https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1429066.html
Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
arch/mips/include/asm/processor.h | 4 +--
arch/mips/mm/mmap.c | 57 -------------------------------
2 files changed, 2 insertions(+), 59 deletions(-)
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index aca909bd7841..f8e04962b52d 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -30,9 +30,9 @@
extern unsigned int vced_count, vcei_count;
/*
- * MIPS does have an arch_pick_mmap_layout()
+ * MIPS uses the default implementation of topdown mmap layout.
*/
-#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
+#define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
#ifdef CONFIG_32BIT
#ifdef CONFIG_KVM_GUEST
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 2f616ebeb7e0..61e65a69bb09 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -20,33 +20,6 @@
unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
EXPORT_SYMBOL(shm_align_mask);
-/* gap between mmap and stack */
-#define MIN_GAP (128*1024*1024UL)
-#define MAX_GAP ((TASK_SIZE)/6*5)
-
-static int mmap_is_legacy(struct rlimit *rlim_stack)
-{
- if (current->personality & ADDR_COMPAT_LAYOUT)
- return 1;
-
- if (rlim_stack->rlim_cur == RLIM_INFINITY)
- return 1;
-
- return sysctl_legacy_va_layout;
-}
-
-static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
-{
- unsigned long gap = rlim_stack->rlim_cur;
-
- if (gap < MIN_GAP)
- gap = MIN_GAP;
- else if (gap > MAX_GAP)
- gap = MAX_GAP;
-
- return PAGE_ALIGN(TASK_SIZE - gap - rnd);
-}
-
#define COLOUR_ALIGN(addr, pgoff) \
((((addr) + shm_align_mask) & ~shm_align_mask) + \
(((pgoff) << PAGE_SHIFT) & shm_align_mask))
@@ -144,36 +117,6 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
addr0, len, pgoff, flags, DOWN);
}
-unsigned long arch_mmap_rnd(void)
-{
- unsigned long rnd;
-
-#ifdef CONFIG_COMPAT
- if (TASK_IS_32BIT_ADDR)
- rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
- else
-#endif /* CONFIG_COMPAT */
- rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
-
- return rnd << PAGE_SHIFT;
-}
-
-void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
-{
- unsigned long random_factor = 0UL;
-
- if (current->flags & PF_RANDOMIZE)
- random_factor = arch_mmap_rnd();
-
- if (mmap_is_legacy(rlim_stack)) {
- mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
- mm->get_unmapped_area = arch_get_unmapped_area;
- } else {
- mm->mmap_base = mmap_base(random_factor, rlim_stack);
- mm->get_unmapped_area = arch_get_unmapped_area_topdown;
- }
-}
-
static inline unsigned long brk_rnd(void)
{
unsigned long rnd = get_random_long();
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/4] riscv: Make mmap allocation top-down by default
2019-03-22 7:42 [PATCH 0/4] Provide generic top-down mmap layout functions Alexandre Ghiti
` (2 preceding siblings ...)
2019-03-22 7:42 ` [PATCH 3/4] mips: " Alexandre Ghiti
@ 2019-03-22 7:42 ` Alexandre Ghiti
2019-03-22 13:22 ` Christoph Hellwig
3 siblings, 1 reply; 9+ messages in thread
From: Alexandre Ghiti @ 2019-03-22 7:42 UTC (permalink / raw)
To: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
linux-fsdevel, linux-mm
Cc: Alexandre Ghiti
In order to avoid wasting user address space by using bottom-up mmap
allocation scheme, prefer top-down scheme when possible.
Before:
root@qemuriscv64:~# cat /proc/self/maps
00010000-00016000 r-xp 00000000 fe:00 6389 /bin/cat.coreutils
00016000-00017000 r--p 00005000 fe:00 6389 /bin/cat.coreutils
00017000-00018000 rw-p 00006000 fe:00 6389 /bin/cat.coreutils
00018000-00039000 rw-p 00000000 00:00 0 [heap]
1555556000-155556d000 r-xp 00000000 fe:00 7193 /lib/ld-2.28.so
155556d000-155556e000 r--p 00016000 fe:00 7193 /lib/ld-2.28.so
155556e000-155556f000 rw-p 00017000 fe:00 7193 /lib/ld-2.28.so
155556f000-1555570000 rw-p 00000000 00:00 0
1555570000-1555572000 r-xp 00000000 00:00 0 [vdso]
1555574000-1555576000 rw-p 00000000 00:00 0
1555576000-1555674000 r-xp 00000000 fe:00 7187 /lib/libc-2.28.so
1555674000-1555678000 r--p 000fd000 fe:00 7187 /lib/libc-2.28.so
1555678000-155567a000 rw-p 00101000 fe:00 7187 /lib/libc-2.28.so
155567a000-15556a0000 rw-p 00000000 00:00 0
3fffb90000-3fffbb1000 rw-p 00000000 00:00 0 [stack]
After:
root@qemuriscv64:~# cat /proc/self/maps
00010000-00016000 r-xp 00000000 fe:00 6389 /bin/cat.coreutils
00016000-00017000 r--p 00005000 fe:00 6389 /bin/cat.coreutils
00017000-00018000 rw-p 00006000 fe:00 6389 /bin/cat.coreutils
00018000-00039000 rw-p 00000000 00:00 0 [heap]
3ff7eb6000-3ff7ed8000 rw-p 00000000 00:00 0
3ff7ed8000-3ff7fd6000 r-xp 00000000 fe:00 7187 /lib/libc-2.28.so
3ff7fd6000-3ff7fda000 r--p 000fd000 fe:00 7187 /lib/libc-2.28.so
3ff7fda000-3ff7fdc000 rw-p 00101000 fe:00 7187 /lib/libc-2.28.so
3ff7fdc000-3ff7fe2000 rw-p 00000000 00:00 0
3ff7fe4000-3ff7fe6000 r-xp 00000000 00:00 0 [vdso]
3ff7fe6000-3ff7ffd000 r-xp 00000000 fe:00 7193 /lib/ld-2.28.so
3ff7ffd000-3ff7ffe000 r--p 00016000 fe:00 7193 /lib/ld-2.28.so
3ff7ffe000-3ff7fff000 rw-p 00017000 fe:00 7193 /lib/ld-2.28.so
3ff7fff000-3ff8000000 rw-p 00000000 00:00 0
3fff888000-3fff8a9000 rw-p 00000000 00:00 0 [stack]
Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
---
arch/riscv/Kconfig | 12 ++++++++++++
arch/riscv/include/asm/processor.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index eb56c82d8aa1..7661335d1667 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -50,6 +50,18 @@ config RISCV
select ARCH_HAS_PTE_SPECIAL
select HAVE_EBPF_JIT if 64BIT
+config HAVE_ARCH_MMAP_RND_BITS
+ def_bool y
+
+config ARCH_MMAP_RND_BITS_MIN
+ default 18
+
+# max bits determined by the following formula:
+# VA_BITS - PAGE_SHIFT - 3
+config ARCH_MMAP_RND_BITS_MAX
+ default 33 if 64BIT # SV48 based
+ default 18
+
config MMU
def_bool y
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index ce70bceb8872..e68a1b1e144a 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -23,6 +23,7 @@
* space during mmap's.
*/
#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
+#define ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
#define STACK_TOP TASK_SIZE
#define STACK_TOP_MAX STACK_TOP
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 4/4] riscv: Make mmap allocation top-down by default
2019-03-22 7:42 ` [PATCH 4/4] riscv: Make mmap allocation top-down by default Alexandre Ghiti
@ 2019-03-22 13:22 ` Christoph Hellwig
2019-03-23 8:05 ` Alex Ghiti
0 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2019-03-22 13:22 UTC (permalink / raw)
To: Alexandre Ghiti
Cc: Christoph Hellwig, Russell King, Catalin Marinas, Will Deacon,
Ralf Baechle, Paul Burton, James Hogan, Palmer Dabbelt,
Albert Ou, Alexander Viro, Luis Chamberlain, Kees Cook,
linux-arm-kernel, linux-kernel, linux-mips, linux-riscv,
linux-fsdevel, linux-mm
> +config HAVE_ARCH_MMAP_RND_BITS
> + def_bool y
This already is defined in arch/Kconfig, no need to duplicate it
here, just add a select statement.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 4/4] riscv: Make mmap allocation top-down by default
2019-03-22 13:22 ` Christoph Hellwig
@ 2019-03-23 8:05 ` Alex Ghiti
0 siblings, 0 replies; 9+ messages in thread
From: Alex Ghiti @ 2019-03-23 8:05 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Russell King, Catalin Marinas, Will Deacon, Ralf Baechle,
Paul Burton, James Hogan, Palmer Dabbelt, Albert Ou,
Alexander Viro, Luis Chamberlain, Kees Cook, linux-arm-kernel,
linux-kernel, linux-mips, linux-riscv, linux-fsdevel, linux-mm
On 3/22/19 9:22 AM, Christoph Hellwig wrote:
>> +config HAVE_ARCH_MMAP_RND_BITS
>> + def_bool y
> This already is defined in arch/Kconfig, no need to duplicate it
> here, just add a select statement.
Right, I will fix that,
Thanks Christoph,
^ permalink raw reply [flat|nested] 9+ messages in thread