2929
3030#include <stdint.h>
3131#include <stdlib.h>
32+ #include <errno.h>
3233#include <Hypervisor/hv.h>
3334#include <Hypervisor/hv_vmx.h>
3435#include <xhyve/support/misc.h>
3536#include <xhyve/vmm/vmm_mem.h>
3637#include <sys/mman.h>
38+ #include <sys/types.h>
39+ #include <sys/sysctl.h>
40+
41+ /* According to the mono project
42+ https://github.com/mono/mono/commit/a502768b3a24f4251de6a48ba78a27c898968e63
43+ using MAP_JIT causes problems with older macOS versions so we should use it
44+ on Mojave or later. */
45+
46+ static int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_JIT ;
47+
48+ #define OSRELEASE "kern.osrelease"
49+ #define OSRELEASE_MOJAVE 18
50+
51+ static long
52+ vmm_get_kern_osrelease ()
53+ {
54+ char * s ;
55+ size_t len ;
56+ long v ;
57+ if (sysctlbyname (OSRELEASE , NULL , & len , NULL , 0 )) {
58+ xhyve_abort ("vmm_get_kern_osrelease failed to query sysctl kern.osrelease\n" );
59+ }
60+ s = malloc (len );
61+ if (!s ) {
62+ xhyve_abort ("vmm_get_kern_osrelease failed to allocate memory for kern.osrelease\n" );
63+ }
64+ if (sysctlbyname (OSRELEASE , s , & len , NULL , 0 )){
65+ xhyve_abort ("vmm_get_kern_osrelease failed to query sysctl kern.osrelease\n" );
66+ }
67+ v = strtol (s , NULL , 10 );
68+ if ((v == 0 ) && (errno != 0 )) {
69+ xhyve_abort ("vmm_get_kern_osrelease failed to parse sysctl kern.osrelease value\n" );
70+ }
71+ return v ;
72+ }
73+
3774int
3875vmm_mem_init (void )
3976{
77+ if (vmm_get_kern_osrelease () < OSRELEASE_MOJAVE ) {
78+ fprintf (stderr , "Detected macOS older than Mojave, cannot use MAP_JIT\n" );
79+ mmap_flags &= ~MAP_JIT ;
80+ }
4081 return (0 );
4182}
4283
@@ -46,7 +87,7 @@ vmm_mem_alloc(uint64_t gpa, size_t size)
4687{
4788 void * object ;
4889
49- object = mmap (0 , size , PROT_READ |PROT_WRITE |PROT_EXEC , MAP_PRIVATE | MAP_ANONYMOUS , -1 , 0 );
90+ object = mmap (0 , size , PROT_READ |PROT_WRITE |PROT_EXEC , mmap_flags , -1 , 0 );
5091 if (object == MAP_FAILED ) {
5192 xhyve_abort ("vmm_mem_alloc failed in mmap\n" );
5293 }
0 commit comments