From 8a607135fdbd4878c2856447cd5dd138626f8708 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 10 Mar 2024 15:22:51 -0700 Subject: [PATCH 1/4] Linux: Update syscalls for v6.8 --- .../LinuxSyscalls/Arm64/SyscallsEnum.h | 10 ++++++- .../LinuxSyscalls/Syscalls/Passthrough.cpp | 29 +++++++++++++++++++ .../LinuxEmulation/LinuxSyscalls/x32/Info.cpp | 11 +++++++ .../LinuxSyscalls/x32/SyscallsEnum.h | 10 +++++++ .../LinuxSyscalls/x64/SyscallsEnum.h | 9 ++++++ 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Arm64/SyscallsEnum.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/Arm64/SyscallsEnum.h index a93f3d4fb1..988519c71e 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Arm64/SyscallsEnum.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Arm64/SyscallsEnum.h @@ -339,6 +339,15 @@ enum Syscalls_Arm64 { SYSCALL_Arm64_set_mempolicy_home_node = 450, SYSCALL_Arm64_cachestat = 451, SYSCALL_Arm64_fchmodat2 = 452, + SYSCALL_Arm64_map_shadow_stack = 453, + SYSCALL_Arm64_futex_wake = 454, + SYSCALL_Arm64_futex_wait = 455, + SYSCALL_Arm64_futex_requeue = 456, + SYSCALL_Arm64_statmount = 457, + SYSCALL_Arm64_listmount = 458, + SYSCALL_Arm64_lsm_get_self_attr = 459, + SYSCALL_Arm64_lsm_set_self_attr = 460, + SYSCALL_Arm64_lsm_list_modules = 461, SYSCALL_Arm64_MAX = 512, // Unsupported syscalls on this host @@ -466,6 +475,5 @@ enum Syscalls_Arm64 { SYSCALL_Arm64_epoll_ctl_old = ~0, SYSCALL_Arm64_epoll_wait_old = ~0, SYSCALL_Arm64_newfstatat = ~0, - SYSCALL_Arm64_map_shadow_stack = ~0, }; } diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Passthrough.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Passthrough.cpp index 3136437745..f71330e8bd 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Passthrough.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Passthrough.cpp @@ -635,6 +635,35 @@ uint64_t SyscallPassthrough7(FEXCore::Core::CpuStateFrame *Frame, uint64_t arg1, else { REGISTER_SYSCALL_IMPL(set_mempolicy_home_node, UnimplementedSyscallSafe); } + + if (Handler->IsHostKernelVersionAtLeast(6, 8, 0)) { + REGISTER_SYSCALL_IMPL_PASS_FLAGS(futex_wake, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough4); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(futex_wait, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough6); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(futex_requeue, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough4); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(statmount, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough4); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(listmount, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough4); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(lsm_get_self_attr, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough4); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(lsm_set_self_attr, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough4); + REGISTER_SYSCALL_IMPL_PASS_FLAGS(lsm_list_modules, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY, + SyscallPassthrough3); + } + else { + REGISTER_SYSCALL_IMPL(futex_wake, UnimplementedSyscallSafe); + REGISTER_SYSCALL_IMPL(futex_wait, UnimplementedSyscallSafe); + REGISTER_SYSCALL_IMPL(futex_requeue, UnimplementedSyscallSafe); + REGISTER_SYSCALL_IMPL(statmount, UnimplementedSyscallSafe); + REGISTER_SYSCALL_IMPL(listmount, UnimplementedSyscallSafe); + REGISTER_SYSCALL_IMPL(lsm_get_self_attr, UnimplementedSyscallSafe); + REGISTER_SYSCALL_IMPL(lsm_set_self_attr, UnimplementedSyscallSafe); + REGISTER_SYSCALL_IMPL(lsm_list_modules, UnimplementedSyscallSafe); + } } namespace x64 { diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Info.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Info.cpp index 27256304bb..353f2945ed 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Info.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Info.cpp @@ -161,5 +161,16 @@ namespace FEX::HLE::x32 { *usage = usage64; SYSCALL_ERRNO(); }); + + if (Handler->IsHostKernelVersionAtLeast(6, 8, 0)) { + REGISTER_SYSCALL_IMPL_X32(map_shadow_stack, + [](FEXCore::Core::CpuStateFrame *Frame, uint64_t addr, uint64_t size, uint32_t flags) -> uint64_t { + // Claim that shadow stack isn't supported. + return -EOPNOTSUPP; + }); + } + else { + REGISTER_SYSCALL_IMPL_X32(map_shadow_stack, UnimplementedSyscallSafe); + } } } diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/SyscallsEnum.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/SyscallsEnum.h index 4e899216a7..cff8bb54a9 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/SyscallsEnum.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/SyscallsEnum.h @@ -275,6 +275,7 @@ enum Syscalls_x86 { SYSCALL_x86_io_cancel = 249, SYSCALL_x86_fadvise64 = 250, SYSCALL_x86_exit_group = 252, + // No entrypoint. -ENOSYS SYSCALL_x86_lookup_dcookie = 253, SYSCALL_x86_epoll_create = 254, SYSCALL_x86_epoll_ctl = 255, @@ -468,6 +469,15 @@ enum Syscalls_x86 { SYSCALL_x86_set_mempolicy_home_node = 450, SYSCALL_x86_cachestat = 451, SYSCALL_x86_fchmodat2 = 452, + SYSCALL_x86_map_shadow_stack = 453, + SYSCALL_x86_futex_wake = 454, + SYSCALL_x86_futex_wait = 455, + SYSCALL_x86_futex_requeue = 456, + SYSCALL_x86_statmount = 457, + SYSCALL_x86_listmount = 458, + SYSCALL_x86_lsm_get_self_attr = 459, + SYSCALL_x86_lsm_set_self_attr = 460, + SYSCALL_x86_lsm_list_modules = 461, SYSCALL_x86_MAX = 512, }; diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x64/SyscallsEnum.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/x64/SyscallsEnum.h index 9d4c1db796..df5e5de091 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/x64/SyscallsEnum.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x64/SyscallsEnum.h @@ -233,6 +233,7 @@ enum Syscalls_x64 { SYSCALL_x64_io_cancel = 210, // No entrypoint. -ENOSYS SYSCALL_x64_get_thread_area = 211, + // No entrypoint. -ENOSYS SYSCALL_x64_lookup_dcookie = 212, SYSCALL_x64_epoll_create = 213, // No entrypoint. -ENOSYS @@ -389,6 +390,14 @@ enum Syscalls_x64 { SYSCALL_x64_cachestat = 451, SYSCALL_x64_fchmodat2 = 452, SYSCALL_x64_map_shadow_stack = 453, + SYSCALL_x64_futex_wake = 454, + SYSCALL_x64_futex_wait = 455, + SYSCALL_x64_futex_requeue = 456, + SYSCALL_x64_statmount = 457, + SYSCALL_x64_listmount = 458, + SYSCALL_x64_lsm_get_self_attr = 459, + SYSCALL_x64_lsm_set_self_attr = 460, + SYSCALL_x64_lsm_list_modules = 461, SYSCALL_x64_MAX = 512, // Unsupported syscalls on this host From ce7acd9b71cafd1b6145bc480a03776591ece915 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 10 Mar 2024 15:45:34 -0700 Subject: [PATCH 2/4] External/drm-headers: Update to v6.8 --- External/drm-headers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/External/drm-headers b/External/drm-headers index 07099adb70..34a20394f7 160000 --- a/External/drm-headers +++ b/External/drm-headers @@ -1 +1 @@ -Subproject commit 07099adb70f4c068c483e543daa2d2d2b020edda +Subproject commit 34a20394f712bfa8eaacafa01b27759e246ee1d7 From 9ec20c4bef5e86d948092dfbee365ab264b00040 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 10 Mar 2024 15:46:21 -0700 Subject: [PATCH 3/4] Linux/Ioctls: Update ioctl emulation for v6.8 - v3d added an ioctl - drm base added a new ioctl - pvr and xe are new drivers in v6.8 --- .../LinuxEmulation/LinuxSyscalls/x32/Ioctl/drm.h | 5 ++++- .../LinuxEmulation/LinuxSyscalls/x32/Ioctl/drm.inl | 1 + .../LinuxSyscalls/x32/Ioctl/pvr_drm.inl | 14 ++++++++++++++ .../LinuxSyscalls/x32/Ioctl/v3d_drm.inl | 1 + .../LinuxSyscalls/x32/Ioctl/xe_drm.inl | 11 +++++++++++ .../LinuxSyscalls/x32/IoctlEmulation.cpp | 2 ++ 6 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/pvr_drm.inl create mode 100644 Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/xe_drm.inl diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/drm.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/drm.h index 2c444ebfe6..cca77efc53 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/drm.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/drm.h @@ -21,7 +21,9 @@ extern "C" { #include "fex-drm/radeon_drm.h" #include "fex-drm/vc4_drm.h" #include "fex-drm/v3d_drm.h" +#include "fex-drm/pvr_drm.h" #include "fex-drm/virtgpu_drm.h" +#include "fex-drm/xe_drm.h" } #include @@ -1422,7 +1424,8 @@ fex_drm_v3d_submit_csd { #include "LinuxSyscalls/x32/Ioctl/radeon_drm.inl" #include "LinuxSyscalls/x32/Ioctl/vc4_drm.inl" #include "LinuxSyscalls/x32/Ioctl/v3d_drm.inl" - +#include "LinuxSyscalls/x32/Ioctl/pvr_drm.inl" +#include "LinuxSyscalls/x32/Ioctl/xe_drm.inl" } #undef CPYT #undef CPYF diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/drm.inl b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/drm.inl index 2089e21c21..b73dea295b 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/drm.inl +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/drm.inl @@ -123,3 +123,4 @@ _BASIC_META(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL) _CUSTOM_META(DRM_IOCTL_MODE_GETFB2, DRM_IOWR(0xCE, FEX::HLE::x32::DRM::fex_drm_mode_fb_cmd2)) _BASIC_META(DRM_IOCTL_SYNCOBJ_EVENTFD) +_BASIC_META(DRM_IOCTL_MODE_CLOSEFB) diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/pvr_drm.inl b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/pvr_drm.inl new file mode 100644 index 0000000000..208ca393f1 --- /dev/null +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/pvr_drm.inl @@ -0,0 +1,14 @@ +_BASIC_META(DRM_IOCTL_PVR_DEV_QUERY) +_BASIC_META(DRM_IOCTL_PVR_CREATE_BO) +_BASIC_META(DRM_IOCTL_PVR_GET_BO_MMAP_OFFSET) +_BASIC_META(DRM_IOCTL_PVR_CREATE_VM_CONTEXT) +_BASIC_META(DRM_IOCTL_PVR_DESTROY_VM_CONTEXT) +_BASIC_META(DRM_IOCTL_PVR_VM_MAP) +_BASIC_META(DRM_IOCTL_PVR_VM_UNMAP) +_BASIC_META(DRM_IOCTL_PVR_CREATE_CONTEXT) +_BASIC_META(DRM_IOCTL_PVR_DESTROY_CONTEXT) +_BASIC_META(DRM_IOCTL_PVR_CREATE_FREE_LIST) +_BASIC_META(DRM_IOCTL_PVR_DESTROY_FREE_LIST) +_BASIC_META(DRM_IOCTL_PVR_CREATE_HWRT_DATASET) +_BASIC_META(DRM_IOCTL_PVR_DESTROY_HWRT_DATASET) +_BASIC_META(DRM_IOCTL_PVR_SUBMIT_JOBS) diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/v3d_drm.inl b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/v3d_drm.inl index f35373db0d..fbbf19f7e6 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/v3d_drm.inl +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/v3d_drm.inl @@ -9,3 +9,4 @@ _CUSTOM_META(DRM_IOCTL_V3D_SUBMIT_CSD, DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT _BASIC_META(DRM_IOCTL_V3D_PERFMON_CREATE) _BASIC_META(DRM_IOCTL_V3D_PERFMON_DESTROY) _BASIC_META(DRM_IOCTL_V3D_PERFMON_GET_VALUES) +_BASIC_META(DRM_IOCTL_V3D_SUBMIT_CPU) diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/xe_drm.inl b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/xe_drm.inl new file mode 100644 index 0000000000..5fb38c217f --- /dev/null +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/Ioctl/xe_drm.inl @@ -0,0 +1,11 @@ +_BASIC_META(DRM_IOCTL_XE_DEVICE_QUERY) +_BASIC_META(DRM_IOCTL_XE_GEM_CREATE) +_BASIC_META(DRM_IOCTL_XE_GEM_MMAP_OFFSET) +_BASIC_META(DRM_IOCTL_XE_VM_CREATE) +_BASIC_META(DRM_IOCTL_XE_VM_DESTROY) +_BASIC_META(DRM_IOCTL_XE_VM_BIND) +_BASIC_META(DRM_IOCTL_XE_EXEC_QUEUE_CREATE) +_BASIC_META(DRM_IOCTL_XE_EXEC_QUEUE_DESTROY) +_BASIC_META(DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY) +_BASIC_META(DRM_IOCTL_XE_EXEC) +_BASIC_META(DRM_IOCTL_XE_WAIT_USER_FENCE) diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/IoctlEmulation.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/IoctlEmulation.cpp index dcaad8c42e..389c005f62 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/IoctlEmulation.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/x32/IoctlEmulation.cpp @@ -765,6 +765,8 @@ namespace FEX::HLE::x32 { #include "LinuxSyscalls/x32/Ioctl/vc4_drm.inl" #include "LinuxSyscalls/x32/Ioctl/v3d_drm.inl" #include "LinuxSyscalls/x32/Ioctl/virtio_drm.inl" +#include "LinuxSyscalls/x32/Ioctl/pvr_drm.inl" +#include "LinuxSyscalls/x32/Ioctl/xe_drm.inl" #undef _BASIC_META #undef _BASIC_META_VAR From d8202335e0287c69239ab4cc75a97357de042d75 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 10 Mar 2024 15:48:55 -0700 Subject: [PATCH 4/4] Linux: Expose support for v6.8 The new syscalls for futexes are the most interesting part --- Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp index a3b70a6fbe..51c14158da 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp @@ -774,8 +774,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.6.0 - return std::max(KernelVersion(5, 0), std::min(KernelVersion(6, 6), GetHostKernelVersion())); + // We currently only emulate a kernel between the ranges of Kernel 5.0.0 and 6.8.0 + return std::max(KernelVersion(5, 0), std::min(KernelVersion(6, 8), GetHostKernelVersion())); } uint64_t SyscallHandler::HandleSyscall(FEXCore::Core::CpuStateFrame *Frame, FEXCore::HLE::SyscallArguments *Args) {