[PATCH 04/16] mm: Add generic MAP_BELOW_HINT

Charlie Jenkins
2024-08-28T05:49:47Z

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(-)

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