diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 6e47fa286d..5400b97018 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -521,14 +521,29 @@ public: #else fd = memfd_create("HostMemory", 0); #endif - ASSERT_MSG(fd >= 0, "memfd_create failed: {}", strerror(errno)); - - // Defined to extend the file with zeros - int ret = ftruncate(fd, backing_size); - ASSERT_MSG(ret == 0, "ftruncate failed with {}, are you out-of-memory?", strerror(errno)); - - backing_base = static_cast( - mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + bool use_anon = false; + if (fd <= 0) { + LOG_WARNING(Common_Memory, "memfd_create: {}", strerror(errno)); + use_anon = true; + } + if (!use_anon) { + // Defined to extend the file with zeros + int ret = ftruncate(fd, backing_size); + if (ret != 0) { + LOG_WARNING(Common_Memory, "ftruncate: {} (likely out-of-emory)", strerror(errno)); + use_anon = true; + } + } + if (use_anon) { + LOG_WARNING(Common_Memory, "Using private mappings instead of shared ones"); + backing_base = static_cast(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); + if (fd > 0) { + fd = -1; + close(fd); + } + } else { + backing_base = static_cast(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + } ASSERT_MSG(backing_base != MAP_FAILED, "mmap failed: {}", strerror(errno)); // Virtual memory initialization @@ -552,22 +567,18 @@ public: free_manager.AllocateBlock(virtual_base + virtual_offset, length); // Deduce mapping protection flags. - int flags = PROT_NONE; - if (True(perms & MemoryPermission::Read)) { - flags |= PROT_READ; - } - if (True(perms & MemoryPermission::Write)) { - flags |= PROT_WRITE; - } + int prot_flags = PROT_NONE; + if (True(perms & MemoryPermission::Read)) + prot_flags |= PROT_READ; + if (True(perms & MemoryPermission::Write)) + prot_flags |= PROT_WRITE; #ifdef ARCHITECTURE_arm64 - if (True(perms & MemoryPermission::Execute)) { - flags |= PROT_EXEC; - } + if (True(perms & MemoryPermission::Execute)) + prot_flags |= PROT_EXEC; #endif - - void* ret = mmap(virtual_base + virtual_offset, length, flags, MAP_SHARED | MAP_FIXED, fd, - host_offset); - ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); + int flags = (fd > 0 ? MAP_SHARED : MAP_PRIVATE) | MAP_FIXED; + void* ret = mmap(virtual_base + virtual_offset, length, prot_flags, flags, fd, host_offset); + ASSERT_MSG(ret != MAP_FAILED, "mmap: {}", strerror(errno)); } void Unmap(size_t virtual_offset, size_t length) { diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 0022d242c3..6800c20f69 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -169,7 +169,7 @@ bool IsFastmemEnabled() { if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe) { return bool(values.cpuopt_unsafe_host_mmu); } -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) +#if !defined(__APPLE__) && !defined(__linux__) && !defined(__ANDROID__) && !defined(_WIN32) return false; #else return true; diff --git a/src/common/settings.h b/src/common/settings.h index 0b61da88f9..6bcd97f2f3 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -296,7 +296,7 @@ struct Values { Category::CpuDebug}; SwitchableSetting cpuopt_unsafe_host_mmu{linkage, -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) +#if !defined(__APPLE__) && !defined(__linux__) && !defined(__ANDROID__) && !defined(_WIN32) false, #else true, diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 5fcc928b86..eca2bb33bb 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -292,7 +292,7 @@ std::shared_ptr ArmDynarmic32::MakeJit(Common::PageTable* pa // Curated optimizations case Settings::CpuAccuracy::Auto: config.unsafe_optimizations = true; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) || defined(__DragonFly__) config.fastmem_pointer = std::nullopt; config.fastmem_exclusive_access = false; #endif diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 55975f4cdc..a87130f6dc 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -351,7 +351,7 @@ std::shared_ptr ArmDynarmic64::MakeJit(Common::PageTable* pa // Safe optimisations case Settings::CpuAccuracy::Auto: config.unsafe_optimizations = true; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) +#if !defined(__APPLE__) && !defined(__linux__) && !defined(__ANDROID__) && !defined(_WIN32) config.fastmem_pointer = std::nullopt; config.fastmem_exclusive_access = false; #endif