diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e7ee8b3d..32c2da279 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -422,16 +422,6 @@ else() # list(APPEND mi_defines MI_WIN_INIT_USE_CRT_TLS=1) endif() -# Check /proc/cpuinfo for an SV39 MMU and limit the virtual address bits. -# (this will skip the aligned hinting in that case. Issue #939, #949) -if (EXISTS /proc/cpuinfo) - file(STRINGS /proc/cpuinfo mi_sv39_mmu REGEX "^mmu[ \t]+:[ \t]+sv39$") - if (mi_sv39_mmu) - MESSAGE( STATUS "Set virtual address bits to 39 (SV39 MMU detected)" ) - list(APPEND mi_defines MI_DEFAULT_VIRTUAL_ADDRESS_BITS=39) - endif() -endif() - # On Haiku use `-DCMAKE_INSTALL_PREFIX` instead, issue #788 # if(CMAKE_SYSTEM_NAME MATCHES "Haiku") # SET(CMAKE_INSTALL_LIBDIR ~/config/non-packaged/lib) diff --git a/src/prim/unix/prim.c b/src/prim/unix/prim.c index 3bffd2912..3d3ea939b 100644 --- a/src/prim/unix/prim.c +++ b/src/prim/unix/prim.c @@ -41,6 +41,13 @@ terms of the MIT license. A copy of the license can be found in the file #else #include #endif + #if defined(__riscv) || defined(_M_RISCV) + #if __has_include() + #include + #elif __has_include() + #include + #endif + #endif #elif defined(__APPLE__) #include #include @@ -187,6 +194,31 @@ static void unix_detect_physical_memory( size_t page_size, size_t* physical_memo #endif } +// Detect the virtual address bits (currently Linux/RISC-V only) +static size_t unix_detect_virtual_address_bits(void) +{ + #ifdef RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS + struct riscv_hwprobe probe = { + .key = RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS, + }; + + // Prefer the GNU libc interface if available, as it can also use the VDSO + #if __has_include() + if (__riscv_hwprobe(&probe, 1, 0, NULL, 0) == 0) { + #else + if (syscall(__NR_riscv_hwprobe, &probe, 1, 0, NULL, 0) == 0) { + #endif + // If a key is unknown to the kernel, its key field will be cleared to -1. + if (probe.key != -1) { + return MI_SIZE_BITS - mi_clz((uintptr_t)probe.value); + } + } + #endif + + // default: MI_MAX_VABITS + return MI_MAX_VABITS; +} + void _mi_prim_mem_init( mi_os_mem_config_t* config ) { long psize = sysconf(_SC_PAGESIZE); @@ -199,6 +231,7 @@ void _mi_prim_mem_init( mi_os_mem_config_t* config ) config->has_overcommit = unix_detect_overcommit(); config->has_partial_free = true; // mmap can free in parts config->has_virtual_reserve = true; // todo: check if this true for NetBSD? (for anonymous mmap with PROT_NONE) + config->virtual_address_bits = unix_detect_virtual_address_bits(); // disable transparent huge pages for this process? #if (defined(__linux__) || defined(__ANDROID__)) && defined(PR_GET_THP_DISABLE)