From 12bdfd28e447fa6caeb615cd915cc74df665b763 Mon Sep 17 00:00:00 2001 From: Seg Date: Thu, 26 Nov 2020 14:42:02 -0800 Subject: [PATCH 1/3] Fix low memory allocation on aarch64 linux. --- BasiliskII/src/CrossPlatform/vm_alloc.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.cpp b/BasiliskII/src/CrossPlatform/vm_alloc.cpp index 005cb727c..aef1ff983 100644 --- a/BasiliskII/src/CrossPlatform/vm_alloc.cpp +++ b/BasiliskII/src/CrossPlatform/vm_alloc.cpp @@ -83,6 +83,10 @@ typedef unsigned long vm_uintptr_t; #define MAP_ANONYMOUS 0 #endif +/* NOTE: on linux MAP_32BIT is only implemented on AMD64 + it is a null op on all other architectures + thus the MAP_BASE setting below is the only thing + ensuring low addresses on aarch64 for example */ #define MAP_EXTRA_FLAGS (MAP_32BIT) #ifdef HAVE_MMAP_VM @@ -92,7 +96,17 @@ typedef unsigned long vm_uintptr_t; NOTE: this is empirically determined on Linux/x86. */ #define MAP_BASE 0x10000000 #else -#define MAP_BASE 0x00000000 +/* linux does not implement any useful fallback behavior + such as allocating the next available address + and the first 4k of address space is marked unavailable + for security reasons (see https://wiki.debian.org/mmap_min_addr) + so we must start requesting after the first page + (or we get a high 64bit address and break on aarch64) + + leaving NULL unmapped is a good idea anyway for debugging reasons + so we do this unconditionally on all platforms + some of which use upwards of 64k pages, so lets start there, just in case */ +#define MAP_BASE 0x00010000 #endif static char * next_address = (char *)MAP_BASE; #ifdef HAVE_MMAP_ANON From 2dfd717e89e724166c2da6ba3e6338cd02c8bd80 Mon Sep 17 00:00:00 2001 From: Seg Date: Fri, 27 Nov 2020 01:39:50 -0800 Subject: [PATCH 2/3] Don't break real addressing. --- BasiliskII/src/CrossPlatform/vm_alloc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.cpp b/BasiliskII/src/CrossPlatform/vm_alloc.cpp index aef1ff983..cd6636363 100644 --- a/BasiliskII/src/CrossPlatform/vm_alloc.cpp +++ b/BasiliskII/src/CrossPlatform/vm_alloc.cpp @@ -95,7 +95,7 @@ typedef unsigned long vm_uintptr_t; don't get addresses above when the program is run on AMD64. NOTE: this is empirically determined on Linux/x86. */ #define MAP_BASE 0x10000000 -#else +#elif !REAL_ADDRESSING /* linux does not implement any useful fallback behavior such as allocating the next available address and the first 4k of address space is marked unavailable @@ -107,6 +107,8 @@ typedef unsigned long vm_uintptr_t; so we do this unconditionally on all platforms some of which use upwards of 64k pages, so lets start there, just in case */ #define MAP_BASE 0x00010000 +#else /* must be 0x0 when REAL_ADDRESSING=1 */ +#define MAP_BASE 0x00000000 #endif static char * next_address = (char *)MAP_BASE; #ifdef HAVE_MMAP_ANON From 45e5b4e28e07349fddd798d66b6dd79c4ce16415 Mon Sep 17 00:00:00 2001 From: Seg Date: Fri, 27 Nov 2020 12:52:25 -0800 Subject: [PATCH 3/3] SELinux on CentOS blocks the first 64k --- BasiliskII/src/CrossPlatform/vm_alloc.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/BasiliskII/src/CrossPlatform/vm_alloc.cpp b/BasiliskII/src/CrossPlatform/vm_alloc.cpp index cd6636363..32e362361 100644 --- a/BasiliskII/src/CrossPlatform/vm_alloc.cpp +++ b/BasiliskII/src/CrossPlatform/vm_alloc.cpp @@ -98,14 +98,13 @@ typedef unsigned long vm_uintptr_t; #elif !REAL_ADDRESSING /* linux does not implement any useful fallback behavior such as allocating the next available address - and the first 4k of address space is marked unavailable + and the first 4k-64k of address space is marked unavailable for security reasons (see https://wiki.debian.org/mmap_min_addr) so we must start requesting after the first page (or we get a high 64bit address and break on aarch64) leaving NULL unmapped is a good idea anyway for debugging reasons - so we do this unconditionally on all platforms - some of which use upwards of 64k pages, so lets start there, just in case */ + so we do this unconditionally on all platforms */ #define MAP_BASE 0x00010000 #else /* must be 0x0 when REAL_ADDRESSING=1 */ #define MAP_BASE 0x00000000