From 24d61e112580ec92e6c82b0f2df92f2641b9798b Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Wed, 6 Aug 2025 22:01:56 +0100 Subject: [PATCH] Windows: Enable downstream kernel-side unaligned atomic handling --- Source/Windows/ARM64EC/Module.cpp | 3 +-- Source/Windows/Common/TSOHandlerConfig.h | 18 +++++++++++++++++- Source/Windows/WOW64/Module.cpp | 3 +-- Source/Windows/include/winternl.h | 6 ++++++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index 723465800..e60ae29a4 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -640,7 +640,6 @@ NTSTATUS ProcessInit() { SignalDelegator = fextl::make_unique(); SyscallHandler = fextl::make_unique(); - Exception::HandlerConfig.emplace(); const auto NtDll = GetModuleHandle("ntdll.dll"); const bool IsWine = !!GetProcAddress(NtDll, "wine_get_version"); @@ -654,7 +653,7 @@ NTSTATUS ProcessInit() { CTX->SetSignalDelegator(SignalDelegator.get()); CTX->SetSyscallHandler(SyscallHandler.get()); CTX->InitCore(); - + Exception::HandlerConfig.emplace(*CTX); InvalidationTracker.emplace(*CTX, Threads); HandleImageMap(NtDllBase); diff --git a/Source/Windows/Common/TSOHandlerConfig.h b/Source/Windows/Common/TSOHandlerConfig.h index fbd84a571..cec36ec41 100644 --- a/Source/Windows/Common/TSOHandlerConfig.h +++ b/Source/Windows/Common/TSOHandlerConfig.h @@ -1,18 +1,32 @@ // SPDX-License-Identifier: MIT #pragma once +#include #include #include namespace FEX::Windows { class TSOHandlerConfig final { public: - TSOHandlerConfig() { + TSOHandlerConfig(FEXCore::Context::Context& CTX) { if (HalfBarrierTSOEnabled()) { UnalignedHandlerType = FEXCore::ArchHelpers::Arm64::UnalignedHandlerType::HalfBarrier; } else { UnalignedHandlerType = FEXCore::ArchHelpers::Arm64::UnalignedHandlerType::NonAtomic; } + + if (TSOEnabled()) { + BOOL Enable = TRUE; + NTSTATUS Status = NtSetInformationProcess(NtCurrentProcess(), ProcessFexHardwareTso, &Enable, sizeof(Enable)); + if (Status == STATUS_SUCCESS) { + CTX.SetHardwareTSOSupport(true); + } + } + + uint64_t Flags = + (StrictInProcessSplitLocks() ? FEX_UNALIGN_ATOMIC_STRICT_SPLIT_LOCKS : 0) | FEX_UNALIGN_ATOMIC_BACKPATCH | FEX_UNALIGN_ATOMIC_EMULATE; + + NtSetInformationProcess(NtCurrentProcess(), ProcessFexUnalignAtomic, &Flags, sizeof(Flags)); } FEXCore::ArchHelpers::Arm64::UnalignedHandlerType GetUnalignedHandlerType() const { @@ -20,7 +34,9 @@ public: } private: + FEX_CONFIG_OPT(TSOEnabled, TSOENABLED); FEX_CONFIG_OPT(HalfBarrierTSOEnabled, HALFBARRIERTSOENABLED); + FEX_CONFIG_OPT(StrictInProcessSplitLocks, STRICTINPROCESSSPLITLOCKS); FEXCore::ArchHelpers::Arm64::UnalignedHandlerType UnalignedHandlerType {FEXCore::ArchHelpers::Arm64::UnalignedHandlerType::HalfBarrier}; }; diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index 4d539ca7e..c51f4f902 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -523,7 +523,6 @@ void BTCpuProcessInit() { SignalDelegator = fextl::make_unique(); SyscallHandler = fextl::make_unique(); - Context::HandlerConfig.emplace(); const auto NtDll = GetModuleHandle("ntdll.dll"); const bool IsWine = !!GetProcAddress(NtDll, "wine_get_version"); OvercommitTracker.emplace(IsWine); @@ -538,7 +537,7 @@ void BTCpuProcessInit() { CTX->SetSignalDelegator(SignalDelegator.get()); CTX->SetSyscallHandler(SyscallHandler.get()); CTX->InitCore(); - + Context::HandlerConfig.emplace(*CTX); InvalidationTracker.emplace(*CTX, Threads); auto NtDllX86 = reinterpret_cast(GetProcAddress(NtDll, "LdrSystemDllInitBlock"))->ntdll_handle; diff --git a/Source/Windows/include/winternl.h b/Source/Windows/include/winternl.h index 9607087f4..efd211c5a 100644 --- a/Source/Windows/include/winternl.h +++ b/Source/Windows/include/winternl.h @@ -455,6 +455,12 @@ typedef enum _MEMORY_INFORMATION_CLASS { #define SystemEmulationBasicInformation (SYSTEM_INFORMATION_CLASS)62 #define ProcessFexHardwareTso (PROCESSINFOCLASS)2000 +#define ProcessFexUnalignAtomic (PROCESSINFOCLASS)2001 + +// These match the prctl flag values +#define FEX_UNALIGN_ATOMIC_EMULATE (1ULL << 0) +#define FEX_UNALIGN_ATOMIC_BACKPATCH (1ULL << 1) +#define FEX_UNALIGN_ATOMIC_STRICT_SPLIT_LOCKS (1ULL << 2) typedef enum _KEY_VALUE_INFORMATION_CLASS { KeyValueBasicInformation,