Make the generic implementation of arch_get_mmap_base() and
arch_get_mmap_end() support MAP_BELOW_HINT.

Signed-off-by: Charlie Jenkins <char...@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


Reply via email to