@@ -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,
Make the generic implementation of arch_get_mmap_base() and arch_get_mmap_end() support MAP_BELOW_HINT. Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> --- include/linux/sched/mm.h | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-)