diff --git a/Readme.md b/Readme.md index bff42213e0..8c529165f2 100644 --- a/Readme.md +++ b/Readme.md @@ -2,7 +2,7 @@ # FEX - Fast x86 emulation frontend FEX allows you to run x86 and x86-64 binaries on an AArch64 host, similar to qemu-user and box86. It has native support for a rootfs overlay, so you don't need to chroot, as well as some thunklibs so it can forward things like GL to the host. -FEX presents a Linux 5.0+ interface to the guest, and supports only AArch64 as a host. +FEX presents a Linux 5.15+ interface to the guest, and supports only AArch64 as a host. FEX is very much work in progress, so expect things to change. diff --git a/Source/Tools/FEXLoader/FEXLoader.cpp b/Source/Tools/FEXLoader/FEXLoader.cpp index 60a8c49936..b39329bf27 100644 --- a/Source/Tools/FEXLoader/FEXLoader.cpp +++ b/Source/Tools/FEXLoader/FEXLoader.cpp @@ -439,9 +439,8 @@ int main(int argc, char** argv, char** const envp) { } uint32_t KernelVersion = FEX::HLE::SyscallHandler::CalculateHostKernelVersion(); - if (KernelVersion < FEX::HLE::SyscallHandler::KernelVersion(4, 17)) { - // We require 4.17 minimum for MAP_FIXED_NOREPLACE - LogMan::Msg::EFmt("FEXLoader requires kernel 4.17 minimum. Expect problems."); + if (KernelVersion < FEX::HLE::SyscallHandler::KernelVersion(5, 15)) { + LogMan::Msg::EFmt("FEXLoader requires kernel 5.15 minimum. Expect problems."); } // Before we go any further, set all of our host environment variables that the config has provided diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp index 82ba52839f..c6d3a8d680 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp @@ -333,8 +333,6 @@ FileManager::FileManager(FEXCore::Context::Context* ctx) ProcFSDev = Buffer.st_dev; } - uint32_t KernelVersion = FEX::HLE::SyscallHandler::CalculateHostKernelVersion(); - HasOpenat2 = KernelVersion >= FEX::HLE::SyscallHandler::KernelVersion(5, 8, 0); UpdatePID(::getpid()); } @@ -648,17 +646,16 @@ uint64_t FileManager::Open(const char* pathname, int flags, uint32_t mode) { if (!ShouldSkipOpenInEmu(flags)) { FDPathTmpData TmpFilename; - auto Path = GetEmulatedFDPath(AT_FDCWD, SelfPath, !HasOpenat2, TmpFilename); + auto Path = GetEmulatedFDPath(AT_FDCWD, SelfPath, false, TmpFilename); if (Path.first != -1) { FEX::HLE::open_how how = { .flags = (uint64_t)flags, .mode = (flags & (O_CREAT | O_TMPFILE)) ? mode & 07777 : 0, // openat2() is stricter about this .resolve = (Path.first == AT_FDCWD) ? 0u : RESOLVE_IN_ROOT, // AT_FDCWD means it's a thunk and not via RootFS }; - if (HasOpenat2) { - fd = ::syscall(SYSCALL_DEF(openat2), Path.first, Path.second, &how, sizeof(how)); - } - if (fd == -1 && (!HasOpenat2 || errno == EXDEV)) { + fd = ::syscall(SYSCALL_DEF(openat2), Path.first, Path.second, &how, sizeof(how)); + + if (fd == -1 && errno == EXDEV) { // This means a magic symlink (/proc/foo) was involved. In this case we // just punt and do the access without RESOLVE_IN_ROOT. fd = ::syscall(SYSCALL_DEF(openat), Path.first, Path.second, flags, mode); @@ -903,17 +900,15 @@ uint64_t FileManager::Openat([[maybe_unused]] int dirfs, const char* pathname, i if (!ShouldSkipOpenInEmu(flags)) { FDPathTmpData TmpFilename; - auto Path = GetEmulatedFDPath(dirfs, SelfPath, !HasOpenat2, TmpFilename); + auto Path = GetEmulatedFDPath(dirfs, SelfPath, false, TmpFilename); if (Path.first != -1) { FEX::HLE::open_how how = { .flags = (uint64_t)flags, .mode = (flags & (O_CREAT | O_TMPFILE)) ? mode & 07777 : 0, // openat2() is stricter about this, .resolve = (Path.first == AT_FDCWD) ? 0u : RESOLVE_IN_ROOT, // AT_FDCWD means it's a thunk and not via RootFS }; - if (HasOpenat2) { - fd = ::syscall(SYSCALL_DEF(openat2), Path.first, Path.second, &how, sizeof(how)); - } - if (fd == -1 && (!HasOpenat2 || errno == EXDEV)) { + fd = ::syscall(SYSCALL_DEF(openat2), Path.first, Path.second, &how, sizeof(how)); + if (fd == -1 && errno == EXDEV) { // This means a magic symlink (/proc/foo) was involved. In this case we // just punt and do the access without RESOLVE_IN_ROOT. fd = ::syscall(SYSCALL_DEF(openat), Path.first, Path.second, flags, mode); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.h index 7644bc612f..77d50d44e3 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.h @@ -170,6 +170,5 @@ class FileManager final { int64_t RootFSFDInode = 0; int64_t ProcFDInode = 0; dev_t ProcFSDev; - bool HasOpenat2; }; } // namespace FEX::HLE diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp index 4cc4d432b2..eded499f71 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp @@ -808,8 +808,8 @@ uint32_t SyscallHandler::CalculateHostKernelVersion() { } uint32_t SyscallHandler::CalculateGuestKernelVersion() { - // We currently only emulate a kernel between the ranges of Kernel 5.0.0 and 6.11.0 - return std::max(KernelVersion(5, 0), std::min(KernelVersion(6, 11), GetHostKernelVersion())); + // We currently only emulate a kernel between the ranges of Kernel 5.15.0 and 6.11.0 + return std::max(KernelVersion(5, 15), std::min(KernelVersion(6, 11), GetHostKernelVersion())); } uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::CpuStateFrame* Frame, FEXCore::HLE::SyscallArguments* Args) { diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/FD.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/FD.cpp index 38c407b1b8..5b42e0ae53 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/FD.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/FD.cpp @@ -110,29 +110,22 @@ void RegisterFD(FEX::HLE::SyscallHandler* Handler) { SYSCALL_ERRNO(); }); - if (Handler->IsHostKernelVersionAtLeast(5, 8, 0)) { - // Only exists on kernel 5.8+ - REGISTER_SYSCALL_IMPL_FLAGS(faccessat2, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - [](FEXCore::Core::CpuStateFrame* Frame, int dirfd, const char* pathname, int mode, int flags) -> uint64_t { - uint64_t Result = FEX::HLE::_SyscallHandler->FM.FAccessat2(dirfd, pathname, mode, flags); - SYSCALL_ERRNO(); - }); - - REGISTER_SYSCALL_IMPL_FLAGS( - openat2, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - [](FEXCore::Core::CpuStateFrame* Frame, int dirfs, const char* pathname, struct open_how* how, size_t usize) -> uint64_t { - open_how HostHow {}; - size_t HostSize = std::min(sizeof(open_how), usize); - memcpy(&HostHow, how, HostSize); - - HostHow.flags = FEX::HLE::RemapFromX86Flags(HostHow.flags); - uint64_t Result = FEX::HLE::_SyscallHandler->FM.Openat2(dirfs, pathname, &HostHow, HostSize); - SYSCALL_ERRNO(); - }); - } else { - REGISTER_SYSCALL_IMPL(faccessat2, UnimplementedSyscallSafe); - REGISTER_SYSCALL_IMPL(openat2, UnimplementedSyscallSafe); - } + REGISTER_SYSCALL_IMPL_FLAGS(faccessat2, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + [](FEXCore::Core::CpuStateFrame* Frame, int dirfd, const char* pathname, int mode, int flags) -> uint64_t { + uint64_t Result = FEX::HLE::_SyscallHandler->FM.FAccessat2(dirfd, pathname, mode, flags); + SYSCALL_ERRNO(); + }); + + REGISTER_SYSCALL_IMPL_FLAGS(openat2, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + [](FEXCore::Core::CpuStateFrame* Frame, int dirfs, const char* pathname, struct open_how* how, size_t usize) -> uint64_t { + open_how HostHow {}; + size_t HostSize = std::min(sizeof(open_how), usize); + memcpy(&HostHow, how, HostSize); + + HostHow.flags = FEX::HLE::RemapFromX86Flags(HostHow.flags); + uint64_t Result = FEX::HLE::_SyscallHandler->FM.Openat2(dirfs, pathname, &HostHow, HostSize); + SYSCALL_ERRNO(); + }); REGISTER_SYSCALL_IMPL_FLAGS(eventfd, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, [](FEXCore::Core::CpuStateFrame* Frame, uint32_t count) -> uint64_t { @@ -155,14 +148,10 @@ void RegisterFD(FEX::HLE::SyscallHandler* Handler) { SYSCALL_ERRNO(); }); - if (Handler->IsHostKernelVersionAtLeast(5, 9, 0)) { - REGISTER_SYSCALL_IMPL_FLAGS(close_range, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - [](FEXCore::Core::CpuStateFrame* Frame, unsigned int first, unsigned int last, unsigned int flags) -> uint64_t { - uint64_t Result = FEX::HLE::_SyscallHandler->FM.CloseRange(first, last, flags); - SYSCALL_ERRNO(); - }); - } else { - REGISTER_SYSCALL_IMPL(close_range, UnimplementedSyscallSafe); - } + REGISTER_SYSCALL_IMPL_FLAGS(close_range, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + [](FEXCore::Core::CpuStateFrame* Frame, unsigned int first, unsigned int last, unsigned int flags) -> uint64_t { + uint64_t Result = FEX::HLE::_SyscallHandler->FM.CloseRange(first, last, flags); + SYSCALL_ERRNO(); + }); } } // namespace FEX::HLE diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Passthrough.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Passthrough.cpp index b75d09dfcd..b8545a4552 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Passthrough.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Passthrough.cpp @@ -492,90 +492,42 @@ void RegisterCommon(FEX::HLE::SyscallHandler* Handler) { SyscallPassthrough2); REGISTER_SYSCALL_IMPL_PASS_FLAGS(pkey_free, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, SyscallPassthrough1); - if (Handler->IsHostKernelVersionAtLeast(5, 1, 0)) { - REGISTER_SYSCALL_IMPL_PASS_FLAGS(io_uring_setup, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough2); - REGISTER_SYSCALL_IMPL_PASS_FLAGS(io_uring_enter, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough6); - REGISTER_SYSCALL_IMPL_PASS_FLAGS(io_uring_register, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough4); - REGISTER_SYSCALL_IMPL_PASS_FLAGS(open_tree, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough3); - REGISTER_SYSCALL_IMPL_PASS_FLAGS(move_mount, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough5); - REGISTER_SYSCALL_IMPL_PASS_FLAGS(fsopen, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough3); - REGISTER_SYSCALL_IMPL_PASS_FLAGS(fsconfig, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough5); - REGISTER_SYSCALL_IMPL_PASS_FLAGS(fsmount, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough3); - REGISTER_SYSCALL_IMPL_PASS_FLAGS(fspick, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough3); - } else { - REGISTER_SYSCALL_IMPL(io_uring_setup, UnimplementedSyscallSafe); - REGISTER_SYSCALL_IMPL(io_uring_enter, UnimplementedSyscallSafe); - REGISTER_SYSCALL_IMPL(io_uring_register, UnimplementedSyscallSafe); - REGISTER_SYSCALL_IMPL(open_tree, UnimplementedSyscallSafe); - REGISTER_SYSCALL_IMPL(move_mount, UnimplementedSyscallSafe); - REGISTER_SYSCALL_IMPL(fsopen, UnimplementedSyscallSafe); - REGISTER_SYSCALL_IMPL(fsconfig, UnimplementedSyscallSafe); - REGISTER_SYSCALL_IMPL(fsmount, UnimplementedSyscallSafe); - REGISTER_SYSCALL_IMPL(fspick, UnimplementedSyscallSafe); - } - if (Handler->IsHostKernelVersionAtLeast(5, 3, 0)) { - REGISTER_SYSCALL_IMPL_PASS_FLAGS(pidfd_open, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough2); - } else { - REGISTER_SYSCALL_IMPL(pidfd_open, UnimplementedSyscallSafe); - } - if (Handler->IsHostKernelVersionAtLeast(5, 8, 0)) { - REGISTER_SYSCALL_IMPL_PASS_FLAGS(pidfd_getfd, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough3); - } else { - REGISTER_SYSCALL_IMPL(pidfd_getfd, UnimplementedSyscallSafe); - } - if (Handler->IsHostKernelVersionAtLeast(5, 12, 0)) { - REGISTER_SYSCALL_IMPL_PASS_FLAGS(mount_setattr, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough5); - } else { - REGISTER_SYSCALL_IMPL(mount_setattr, UnimplementedSyscallSafe); - } - if (Handler->IsHostKernelVersionAtLeast(5, 14, 0)) { - REGISTER_SYSCALL_IMPL_PASS_FLAGS(quotactl_fd, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough4); - } else { - REGISTER_SYSCALL_IMPL(quotactl_fd, UnimplementedSyscallSafe); - } - if (Handler->IsHostKernelVersionAtLeast(5, 13, 0)) { - REGISTER_SYSCALL_IMPL_PASS_FLAGS(landlock_create_ruleset, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough3); - } else { - REGISTER_SYSCALL_IMPL(landlock_create_ruleset, UnimplementedSyscallSafe); - } - if (Handler->IsHostKernelVersionAtLeast(5, 13, 0)) { - REGISTER_SYSCALL_IMPL_PASS_FLAGS(landlock_add_rule, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough4); - } else { - REGISTER_SYSCALL_IMPL(landlock_add_rule, UnimplementedSyscallSafe); - } - if (Handler->IsHostKernelVersionAtLeast(5, 13, 0)) { - REGISTER_SYSCALL_IMPL_PASS_FLAGS(landlock_restrict_self, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough2); - } else { - REGISTER_SYSCALL_IMPL(landlock_restrict_self, UnimplementedSyscallSafe); - } - if (Handler->IsHostKernelVersionAtLeast(5, 14, 0)) { - REGISTER_SYSCALL_IMPL_PASS_FLAGS(memfd_secret, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough1); - } else { - REGISTER_SYSCALL_IMPL(memfd_secret, UnimplementedSyscallSafe); - } - if (Handler->IsHostKernelVersionAtLeast(5, 15, 0)) { - REGISTER_SYSCALL_IMPL_PASS_FLAGS(process_mrelease, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough2); - } else { - REGISTER_SYSCALL_IMPL(process_mrelease, UnimplementedSyscallSafe); - } + REGISTER_SYSCALL_IMPL_PASS_FLAGS(io_uring_setup, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough2); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(io_uring_enter, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough6); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(io_uring_register, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough4); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(open_tree, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough3); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(move_mount, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough5); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(fsopen, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough3); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(fsconfig, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough5); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(fsmount, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough3); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(fspick, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough3); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(pidfd_open, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough2); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(pidfd_getfd, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough3); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(mount_setattr, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough5); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(quotactl_fd, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough4); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(landlock_create_ruleset, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough3); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(landlock_add_rule, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough4); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(landlock_restrict_self, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough2); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(memfd_secret, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough1); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(process_mrelease, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough2); if (Handler->IsHostKernelVersionAtLeast(5, 16, 0)) { REGISTER_SYSCALL_IMPL_PASS_FLAGS(futex_waitv, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, SyscallPassthrough5); @@ -764,18 +716,10 @@ namespace x64 { SyscallPassthrough6); REGISTER_SYSCALL_IMPL_X64_PASS_FLAGS(io_pgetevents, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, SyscallPassthrough6); - if (Handler->IsHostKernelVersionAtLeast(5, 1, 0)) { - REGISTER_SYSCALL_IMPL_X64_PASS_FLAGS(pidfd_send_signal, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough4); - } else { - REGISTER_SYSCALL_IMPL_X64(pidfd_send_signal, UnimplementedSyscallSafe); - } - if (Handler->IsHostKernelVersionAtLeast(5, 10, 0)) { - REGISTER_SYSCALL_IMPL_X64_PASS_FLAGS(process_madvise, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, - SyscallPassthrough5); - } else { - REGISTER_SYSCALL_IMPL_X64(process_madvise, UnimplementedSyscallSafe); - } + REGISTER_SYSCALL_IMPL_X64_PASS_FLAGS(pidfd_send_signal, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough4); + REGISTER_SYSCALL_IMPL_X64_PASS_FLAGS(process_madvise, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough5); if (Handler->IsHostKernelVersionAtLeast(6, 5, 0)) { REGISTER_SYSCALL_IMPL_X64_PASS_FLAGS(cachestat, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, SyscallPassthrough4); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/EPoll.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/EPoll.cpp index 539e85ae16..690c1f0862 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/EPoll.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/EPoll.cpp @@ -80,33 +80,29 @@ void RegisterEpoll(FEX::HLE::SyscallHandler* Handler) { SYSCALL_ERRNO(); }); - if (Handler->IsHostKernelVersionAtLeast(5, 11, 0)) { - REGISTER_SYSCALL_IMPL_X32(epoll_pwait2, - [](FEXCore::Core::CpuStateFrame* Frame, int epfd, compat_ptr events, - int maxevent, compat_ptr timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t { - fextl::vector Events(std::max(0, maxevent)); - - struct timespec tp64 {}; - struct timespec* timed_ptr {}; - if (timeout) { - tp64 = *timeout; - timed_ptr = &tp64; - } + REGISTER_SYSCALL_IMPL_X32(epoll_pwait2, + [](FEXCore::Core::CpuStateFrame* Frame, int epfd, compat_ptr events, int maxevent, + compat_ptr timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t { + fextl::vector Events(std::max(0, maxevent)); - uint64_t Result = - ::syscall(SYSCALL_DEF(epoll_pwait2), epfd, Events.data(), maxevent, timed_ptr, sigmask, sigsetsize); + struct timespec tp64 {}; + struct timespec* timed_ptr {}; + if (timeout) { + tp64 = *timeout; + timed_ptr = &tp64; + } + + uint64_t Result = + ::syscall(SYSCALL_DEF(epoll_pwait2), epfd, Events.data(), maxevent, timed_ptr, sigmask, sigsetsize); - if (Result != -1) { - FaultSafeUserMemAccess::VerifyIsWritable(events, sizeof(FEX::HLE::x32::epoll_event32) * Result); - for (size_t i = 0; i < Result; ++i) { - events[i] = Events[i]; - } + if (Result != -1) { + FaultSafeUserMemAccess::VerifyIsWritable(events, sizeof(FEX::HLE::x32::epoll_event32) * Result); + for (size_t i = 0; i < Result; ++i) { + events[i] = Events[i]; } + } - SYSCALL_ERRNO(); - }); - } else { - REGISTER_SYSCALL_IMPL_X32(epoll_pwait2, UnimplementedSyscallSafe); - } + SYSCALL_ERRNO(); + }); } } // namespace FEX::HLE::x32 diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Signals.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Signals.cpp index 745d8f8784..64d5768d84 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Signals.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Signals.cpp @@ -212,24 +212,20 @@ void RegisterSignals(FEX::HLE::SyscallHandler* Handler) { return Result; }); - if (Handler->IsHostKernelVersionAtLeast(5, 1, 0)) { - REGISTER_SYSCALL_IMPL_X32( - pidfd_send_signal, - [](FEXCore::Core::CpuStateFrame* Frame, int pidfd, int sig, compat_ptr info, unsigned int flags) -> uint64_t { - siginfo_t* InfoHost_ptr {}; - siginfo_t InfoHost {}; - if (info) { - FaultSafeUserMemAccess::VerifyIsReadable(info, sizeof(*info)); - InfoHost = *info; - InfoHost_ptr = &InfoHost; - } - - uint64_t Result = ::syscall(SYSCALL_DEF(pidfd_send_signal), pidfd, sig, InfoHost_ptr, flags); - SYSCALL_ERRNO(); - }); - } else { - REGISTER_SYSCALL_IMPL_X32(pidfd_send_signal, UnimplementedSyscallSafe); - } + REGISTER_SYSCALL_IMPL_X32( + pidfd_send_signal, + [](FEXCore::Core::CpuStateFrame* Frame, int pidfd, int sig, compat_ptr info, unsigned int flags) -> uint64_t { + siginfo_t* InfoHost_ptr {}; + siginfo_t InfoHost {}; + if (info) { + FaultSafeUserMemAccess::VerifyIsReadable(info, sizeof(*info)); + InfoHost = *info; + InfoHost_ptr = &InfoHost; + } + + uint64_t Result = ::syscall(SYSCALL_DEF(pidfd_send_signal), pidfd, sig, InfoHost_ptr, flags); + SYSCALL_ERRNO(); + }); REGISTER_SYSCALL_IMPL_X32( rt_sigqueueinfo, [](FEXCore::Core::CpuStateFrame* Frame, pid_t pid, int sig, compat_ptr info) -> uint64_t { diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x64/EPoll.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/x64/EPoll.cpp index 0f6b139218..d1ab9cdf8f 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/x64/EPoll.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x64/EPoll.cpp @@ -74,26 +74,21 @@ void RegisterEpoll(FEX::HLE::SyscallHandler* Handler) { SYSCALL_ERRNO(); }); - if (Handler->IsHostKernelVersionAtLeast(5, 11, 0)) { - REGISTER_SYSCALL_IMPL_X64(epoll_pwait2, - [](FEXCore::Core::CpuStateFrame* Frame, int epfd, FEX::HLE::epoll_event_x86* events, int maxevent, - timespec* timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t { - fextl::vector Events(std::max(0, maxevent)); + REGISTER_SYSCALL_IMPL_X64(epoll_pwait2, + [](FEXCore::Core::CpuStateFrame* Frame, int epfd, FEX::HLE::epoll_event_x86* events, int maxevent, + timespec* timeout, const uint64_t* sigmask, size_t sigsetsize) -> uint64_t { + fextl::vector Events(std::max(0, maxevent)); - uint64_t Result = - ::syscall(SYSCALL_DEF(epoll_pwait2), epfd, Events.data(), maxevent, timeout, sigmask, sigsetsize); + uint64_t Result = ::syscall(SYSCALL_DEF(epoll_pwait2), epfd, Events.data(), maxevent, timeout, sigmask, sigsetsize); - if (Result != -1) { - FaultSafeUserMemAccess::VerifyIsWritable(events, sizeof(FEX::HLE::epoll_event_x86) * Result); - for (size_t i = 0; i < Result; ++i) { - events[i] = Events[i]; - } + if (Result != -1) { + FaultSafeUserMemAccess::VerifyIsWritable(events, sizeof(FEX::HLE::epoll_event_x86) * Result); + for (size_t i = 0; i < Result; ++i) { + events[i] = Events[i]; } + } - SYSCALL_ERRNO(); - }); - } else { - REGISTER_SYSCALL_IMPL_X64(epoll_pwait2, UnimplementedSyscallSafe); - } + SYSCALL_ERRNO(); + }); } } // namespace FEX::HLE::x64