1515 * reserved.
1616 * Copyright (c) 2016-2017 Research Organization for Information Science
1717 * and Technology (RIST). All rights reserved.
18- * Copyright (c) 2016 IBM Corporation. All rights reserved.
18+ * Copyright (c) 2016-2019 IBM Corporation. All rights reserved.
1919 *
2020 * $COPYRIGHT$
2121 *
4848#if defined(HAVE_LINUX_MMAN_H )
4949#include <linux/mman.h>
5050#endif
51+ #if defined(HAVE_SYS_IPC_H )
52+ #include <sys/ipc.h>
53+ #endif
5154
5255#include "memory_patcher.h"
5356#undef opal_memory_changed
@@ -104,15 +107,7 @@ opal_memory_patcher_component_t mca_memory_patcher_component = {
104107 * data. If this can be resolved the two levels can be joined.
105108 */
106109
107- /*
108- * The following block of code is #if 0'ed out because we do not need
109- * to intercept mmap() any more (mmap() only deals with memory
110- * protection; it does not invalidate any rcache entries for a given
111- * region). But if we do someday, this is the code that we'll need.
112- * It's a little non-trivial, so we might as well keep it (and #if 0
113- * it out).
114- */
115- #if 0
110+ #if defined (SYS_mmap )
116111
117112#if defined(HAVE___MMAP ) && !HAVE_DECL___MMAP
118113/* prototype for Apple's internal mmap function */
@@ -121,12 +116,11 @@ void *__mmap (void *start, size_t length, int prot, int flags, int fd, off_t off
121116
122117static void * (* original_mmap )(void * , size_t , int , int , int , off_t );
123118
124- static void * intercept_mmap (void * start , size_t length , int prot , int flags , int fd , off_t offset )
119+ static void * _intercept_mmap (void * start , size_t length , int prot , int flags , int fd , off_t offset )
125120{
126- OPAL_PATCHER_BEGIN ;
127121 void * result = 0 ;
128122
129- if (prot == PROT_NONE ) {
123+ if (( flags & MAP_FIXED ) && ( start != NULL ) ) {
130124 opal_mem_hooks_release_hook (start , length , true);
131125 }
132126
@@ -137,19 +131,20 @@ static void *intercept_mmap(void *start, size_t length, int prot, int flags, int
137131#else
138132 result = (void * )(intptr_t ) memory_patcher_syscall (SYS_mmap , start , length , prot , flags , fd , offset );
139133#endif
140-
141- // I thought we had some issue in the past with the above line for IA32,
142- // like maybe syscall() wouldn't handle that many arguments. But just now
143- // I used gcc -m32 and it worked on a recent system. But there's a possibility
144- // that older ia32 systems may need some other code to make the above syscall.
145134 } else {
146135 result = original_mmap (start , length , prot , flags , fd , offset );
147136 }
148137
149- OPAL_PATCHER_END ;
150138 return result ;
151139}
152140
141+ static void * intercept_mmap (void * start , size_t length , int prot , int flags , int fd , off_t offset )
142+ {
143+ OPAL_PATCHER_BEGIN ;
144+ void * result = _intercept_mmap (start , length , prot , flags , fd , offset );
145+ OPAL_PATCHER_END ;
146+ return result ;
147+ }
153148#endif
154149
155150#if defined (SYS_munmap )
@@ -256,6 +251,9 @@ static int _intercept_madvise (void *start, size_t length, int advice)
256251 int result = 0 ;
257252
258253 if (advice == MADV_DONTNEED ||
254+ #ifdef MADV_FREE
255+ advice == MADV_FREE ||
256+ #endif
259257#ifdef MADV_REMOVE
260258 advice == MADV_REMOVE ||
261259#endif
@@ -341,7 +339,12 @@ static int intercept_brk (void *addr)
341339
342340#endif
343341
344- #if defined(SYS_shmdt ) && defined(__linux__ )
342+ #define HAS_SHMDT (defined(SYS_shmdt) || \
343+ (defined(IPCOP_shmdt) && defined(SYS_ipc)))
344+ #define HAS_SHMAT (defined(SYS_shmat) || \
345+ (defined(IPCOP_shmat) && defined(SYS_ipc)))
346+
347+ #if (HAS_SHMDT || HAS_SHMAT ) && defined(__linux__ )
345348
346349#include <stdio.h>
347350#include <fcntl.h>
@@ -404,6 +407,68 @@ static size_t memory_patcher_get_shm_seg_size (const void *shmaddr)
404407 return seg_size ;
405408}
406409
410+ static size_t get_shm_size (int shmid )
411+ {
412+ struct shmid_ds ds ;
413+ int ret ;
414+
415+ ret = shmctl (shmid , IPC_STAT , & ds );
416+ if (ret < 0 ) {
417+ return 0 ;
418+ }
419+
420+ return ds .shm_segsz ;
421+ }
422+ #endif
423+
424+ #if HAS_SHMAT && defined(__linux__ )
425+ static void * (* original_shmat )(int shmid , const void * shmaddr , int shmflg );
426+
427+ static void * _intercept_shmat (int shmid , const void * shmaddr , int shmflg )
428+ {
429+ void * result = 0 ;
430+
431+ size_t size = get_shm_size (shmid );
432+
433+ if ((shmflg & SHM_REMAP ) && (shmaddr != NULL )) {
434+ // I don't really know what REMAP combined with SHM_RND does, so I'll just
435+ // guess it remaps all the way down to the lower attach_addr, and all the
436+ // way up to the original shmaddr+size
437+ uintptr_t attach_addr = (uintptr_t )shmaddr ;
438+
439+ if (shmflg & SHM_RND ) {
440+ attach_addr -= ((uintptr_t )shmaddr ) % SHMLBA ;
441+ size += ((uintptr_t )shmaddr ) % SHMLBA ;
442+ }
443+ opal_mem_hooks_release_hook ((void * )attach_addr , size , false);
444+ }
445+
446+ if (!original_shmat ) {
447+ #if defined(SYS_shmat )
448+ result = memory_patcher_syscall (SYS_shmat , shmid , shmaddr , shmflg );
449+ #else // IPCOP_shmat
450+ unsigned long ret ;
451+ ret = memory_patcher_syscall (SYS_ipc , IPCOP_shmat ,
452+ shmid , shmflg , & shmaddr , shmaddr );
453+ result = (ret > - (unsigned long )SHMLBA ) ? (void * )ret : (void * )shmaddr ;
454+ #endif
455+ } else {
456+ result = original_shmat (shmid , shmaddr , shmflg );
457+ }
458+
459+ return result ;
460+ }
461+
462+ static void * intercept_shmat (int shmid , const void * shmaddr , int shmflg )
463+ {
464+ OPAL_PATCHER_BEGIN ;
465+ void * result = _intercept_shmat (shmid , shmaddr , shmflg );
466+ OPAL_PATCHER_END ;
467+ return result ;
468+ }
469+ #endif
470+
471+ #if HAS_SHMDT && defined(__linux__ )
407472static int (* original_shmdt ) (const void * );
408473
409474static int _intercept_shmdt (const void * shmaddr )
@@ -417,7 +482,11 @@ static int _intercept_shmdt (const void *shmaddr)
417482 if (original_shmdt ) {
418483 result = original_shmdt (shmaddr );
419484 } else {
485+ #if defined(SYS_shmdt )
420486 result = memory_patcher_syscall (SYS_shmdt , shmaddr );
487+ #else // IPCOP_shmdt
488+ result = memory_patcher_syscall (SYS_ipc , IPCOP_shmdt , 0 , 0 , 0 , shmaddr );
489+ #endif
421490 }
422491
423492 return result ;
@@ -478,9 +547,7 @@ static int patcher_open (void)
478547 /* set memory hooks support level */
479548 opal_mem_hooks_set_support (OPAL_MEMORY_FREE_SUPPORT | OPAL_MEMORY_MUNMAP_SUPPORT );
480549
481- #if 0
482- /* See above block to see why mmap() functionality is #if 0'ed
483- out */
550+ #if defined (SYS_mmap )
484551 rc = opal_patcher -> patch_symbol ("mmap" , (uintptr_t ) intercept_mmap , (uintptr_t * ) & original_mmap );
485552 if (OPAL_SUCCESS != rc ) {
486553 return rc ;
@@ -508,7 +575,14 @@ static int patcher_open (void)
508575 }
509576#endif
510577
511- #if defined(SYS_shmdt ) && defined(__linux__ )
578+ #if HAS_SHMAT && defined(__linux__ )
579+ rc = opal_patcher -> patch_symbol ("shmat" , (uintptr_t ) intercept_shmat , (uintptr_t * ) & original_shmat );
580+ if (OPAL_SUCCESS != rc ) {
581+ return rc ;
582+ }
583+ #endif
584+
585+ #if HAS_SHMDT && defined(__linux__ )
512586 rc = opal_patcher -> patch_symbol ("shmdt" , (uintptr_t ) intercept_shmdt , (uintptr_t * ) & original_shmdt );
513587 if (OPAL_SUCCESS != rc ) {
514588 return rc ;
0 commit comments