Make the generic implementation of arch_get_mmap_base() and arch_get_mmap_end() support MAP_BELOW_HINT. Signed-off-by: Charlie Jenkins <charlie@xxxxxxxxxxxx> --- include/linux/sched/mm.h | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 265b43855d0b..c350bb5ac0a2 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -9,6 +9,7 @@ #include <linux/gfp.h> #include <linux/sync_core.h> #include <linux/sched/coredump.h> +#include <uapi/asm/mman.h> /* * Routines for handling mm_structs @@ -170,11 +171,40 @@ static inline void mm_update_next_owner(struct mm_struct *mm) #ifdef CONFIG_MMU #ifndef arch_get_mmap_end -#define arch_get_mmap_end(addr, len, flags) (TASK_SIZE) +#define arch_get_mmap_end(addr, len, flags) \ +({ \ + unsigned long mmap_end; \ + typeof(flags) _flags = (flags); \ + typeof(addr) _addr = (addr); \ + typeof(len) _len = (len); \ + mmap_end = TASK_SIZE; \ + if (_flags & MAP_BELOW_HINT && _addr != 0) \ + mmap_end = MIN(mmap_end, _addr + _len); \ + mmap_end; \ +}) #endif #ifndef arch_get_mmap_base -#define arch_get_mmap_base(addr, len, base, flags) (base) +/* + * rnd_gap is defined to be (STACK_TOP - _base) due to the definition of + * mmap_base in mm/util.c + * + * Assumes ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT, which all architectures that + * implement generic mmap use + */ +#define arch_get_mmap_base(addr, len, base, flags) \ +({ \ + unsigned long mmap_base; \ + typeof(flags) _flags = (flags); \ + typeof(addr) _addr = (addr); \ + typeof(base) _base = (base); \ + typeof(len) _len = (len); \ + unsigned long rnd_gap = STACK_TOP - _base; \ + mmap_base = _base; \ + if (_flags & MAP_BELOW_HINT && _addr != 0) \ + mmap_base = MIN(mmap_base, (_addr + _len) - rnd_gap); \ + mmap_base; \ +}) #endif extern void arch_pick_mmap_layout(struct mm_struct *mm, -- 2.45.0