From e31e2f7bf5d0275fffdbce50d75f3d6bcf82ce6a Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 1 Jan 2025 11:12:27 -0800 Subject: [PATCH] FEXLoader: Increase minimum kernel requirement from 5.0 to 5.15 Brought up in #4225 where it had issues with Openat2 which was added in 5.8. The main driving force around minimum kernel version requirement is that the lowest kernel version in our CI is 5.15. A benefit to this choice is that this is an LTS release, which is also what Ubuntu 22.04 is shipping. Once the single CI machine is fixed to ship something newer then the next logical choice would be kernel 6.1 which is also LTS, but until then just lift it to 5.15. This version was released in October 2021, and is supported by the kernel developers until 2026. Our previous minimum of 5.0 was released in March 2019, so a two year leap here. This removes the openat2 workaround that was necessary to pass our CI since it is no longer necessary. --- Readme.md | 2 +- Source/Tools/FEXLoader/FEXLoader.cpp | 5 ++--- .../LinuxSyscalls/FileManagement.cpp | 19 +++++++------------ .../LinuxSyscalls/FileManagement.h | 1 - .../LinuxEmulation/LinuxSyscalls/Syscalls.cpp | 4 ++-- 5 files changed, 12 insertions(+), 19 deletions(-) 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) {