From 5a35e119fedb3dd9402fcff9f215ce819bbc174b Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 21 Mar 2024 20:47:36 -0700 Subject: [PATCH 1/2] Telemetry: Adds tracker for non-canonical memory access crash This may be useful for tracking TSO faulting when it manages to fetch stale data. While most TSO crashes are due to nullptr dereferences, this can still check for the corruption case. --- FEXCore/Source/Utils/Telemetry.cpp | 1 + FEXCore/include/FEXCore/Utils/Telemetry.h | 1 + .../Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp | 5 +++++ Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h | 1 + Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h | 2 ++ .../Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp | 5 ++--- 6 files changed, 12 insertions(+), 3 deletions(-) diff --git a/FEXCore/Source/Utils/Telemetry.cpp b/FEXCore/Source/Utils/Telemetry.cpp index c234d390a..30e4317d0 100644 --- a/FEXCore/Source/Utils/Telemetry.cpp +++ b/FEXCore/Source/Utils/Telemetry.cpp @@ -33,6 +33,7 @@ namespace FEXCore::Telemetry { "Uses 32-bit Segment SS", "Uses 32-bit Segment CS", "Uses 32-bit Segment DS", + "Non-Canonical 64-bit address access", }; static bool Enabled {true}; diff --git a/FEXCore/include/FEXCore/Utils/Telemetry.h b/FEXCore/include/FEXCore/Utils/Telemetry.h index 7f9649471..377856058 100644 --- a/FEXCore/include/FEXCore/Utils/Telemetry.h +++ b/FEXCore/include/FEXCore/Utils/Telemetry.h @@ -30,6 +30,7 @@ namespace FEXCore::Telemetry { TYPE_USES_32BIT_SEGMENT_SS, TYPE_USES_32BIT_SEGMENT_CS, TYPE_USES_32BIT_SEGMENT_DS, + TYPE_UNHANDLED_NONCANONICAL_ADDRESS, TYPE_LAST, }; diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp index 39f912c11..510db10bd 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp @@ -1567,6 +1567,11 @@ namespace FEX::HLE { // FEX is hard crashing at this point and won't hit regular shutdown routines. // Add the signal to the crash mask. CrashMask |= (1ULL << Signal); + if (Signal == SIGSEGV && + reinterpret_cast(SigInfo.si_addr) >= SyscallHandler::TASK_MAX_64BIT) { + // Tried accessing invalid non-canonical x86-64 address. + UnhandledNonCanonical = true; + } SaveTelemetry(); #endif diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h index f5d2358c1..b928c86d9 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.h @@ -154,6 +154,7 @@ namespace FEX::HLE { FEX_CONFIG_OPT(Core, CORE); fextl::string const ApplicationName; FEXCORE_TELEMETRY_INIT(CrashMask, TYPE_CRASH_MASK); + FEXCORE_TELEMETRY_INIT(UnhandledNonCanonical, TYPE_UNHANDLED_NONCANONICAL_ADDRESS); enum DefaultBehaviour { DEFAULT_TERM, diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h index 17f684433..f71f442f3 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h @@ -308,6 +308,8 @@ public: bool NeedXIDCheck() const { return NeedToCheckXID; } void DisableXIDCheck() { NeedToCheckXID = false; } + constexpr static uint64_t TASK_MAX_64BIT = (1ULL << 48); + protected: SyscallHandler(FEXCore::Context::Context *_CTX, FEX::HLE::SignalDelegator *_SignalDelegation); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp index b4a091061..513e34167 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp @@ -449,11 +449,10 @@ namespace FEX::HLE { REGISTER_SYSCALL_IMPL_FLAGS(arch_prctl, SyscallFlags::DEFAULT, [](FEXCore::Core::CpuStateFrame *Frame, int code, unsigned long addr) -> uint64_t { - constexpr uint64_t TASK_MAX = (1ULL << 48); // 48-bits until we can query the host side VA sanely. AArch64 doesn't expose this in cpuinfo uint64_t Result{}; switch (code) { case 0x1001: // ARCH_SET_GS - if (addr >= TASK_MAX) { + if (addr >= SyscallHandler::TASK_MAX_64BIT) { // Ignore a non-canonical address return -EPERM; } @@ -461,7 +460,7 @@ namespace FEX::HLE { Result = 0; break; case 0x1002: // ARCH_SET_FS - if (addr >= TASK_MAX) { + if (addr >= SyscallHandler::TASK_MAX_64BIT) { // Ignore a non-canonical address return -EPERM; } From cccf263080007c031bf058e3fdb33e012bf3e4a2 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 21 Mar 2024 21:10:03 -0700 Subject: [PATCH 2/2] InstCountCI: Update for Telemetry offset changes --- unittests/InstructionCountCI/Crypto/H0F3A.json | 4 ++-- unittests/InstructionCountCI/FlagM/Secondary.json | 2 +- .../InstructionCountCI/FlagM/Secondary_OpSize.json | 2 +- unittests/InstructionCountCI/FlagM/VEX_map1.json | 2 +- unittests/InstructionCountCI/H0F38.json | 2 +- unittests/InstructionCountCI/H0F3A.json | 12 ++++++------ unittests/InstructionCountCI/PrimaryGroup.json | 8 ++++---- unittests/InstructionCountCI/Secondary.json | 6 +++--- unittests/InstructionCountCI/Secondary_OpSize.json | 4 ++-- unittests/InstructionCountCI/Secondary_REPNE.json | 2 +- unittests/InstructionCountCI/VEX_map1.json | 6 +++--- unittests/InstructionCountCI/VEX_map2.json | 2 +- unittests/InstructionCountCI/VEX_map3.json | 4 ++-- 13 files changed, 28 insertions(+), 28 deletions(-) diff --git a/unittests/InstructionCountCI/Crypto/H0F3A.json b/unittests/InstructionCountCI/Crypto/H0F3A.json index ba7bbd5e0..238782658 100644 --- a/unittests/InstructionCountCI/Crypto/H0F3A.json +++ b/unittests/InstructionCountCI/Crypto/H0F3A.json @@ -55,7 +55,7 @@ "0x66 0x0f 0x3a 0xdf" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2096]", + "ldr q2, [x28, #2112]", "movi v3.2d, #0x0", "mov v16.16b, v17.16b", "unimplemented (Unimplemented)", @@ -68,7 +68,7 @@ "0x66 0x0f 0x3a 0xdf" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2096]", + "ldr q2, [x28, #2112]", "movi v3.2d, #0x0", "mov v16.16b, v17.16b", "unimplemented (Unimplemented)", diff --git a/unittests/InstructionCountCI/FlagM/Secondary.json b/unittests/InstructionCountCI/FlagM/Secondary.json index c35fc41f3..1982756f1 100644 --- a/unittests/InstructionCountCI/FlagM/Secondary.json +++ b/unittests/InstructionCountCI/FlagM/Secondary.json @@ -1618,7 +1618,7 @@ "Comment": "0x0f 0xd7", "ExpectedArm64ASM": [ "ldr d2, [x28, #768]", - "ldr d3, [x28, #2208]", + "ldr d3, [x28, #2224]", "cmlt v2.16b, v2.16b, #0", "and v2.16b, v2.16b, v3.16b", "addp v2.16b, v2.16b, v2.16b", diff --git a/unittests/InstructionCountCI/FlagM/Secondary_OpSize.json b/unittests/InstructionCountCI/FlagM/Secondary_OpSize.json index 2fc1391da..ce9df6ffe 100644 --- a/unittests/InstructionCountCI/FlagM/Secondary_OpSize.json +++ b/unittests/InstructionCountCI/FlagM/Secondary_OpSize.json @@ -38,7 +38,7 @@ "ExpectedInstructionCount": 7, "Comment": "0x66 0x0f 0xd7", "ExpectedArm64ASM": [ - "ldr q2, [x28, #2208]", + "ldr q2, [x28, #2224]", "cmlt v3.16b, v16.16b, #0", "and v2.16b, v3.16b, v2.16b", "addp v2.16b, v2.16b, v2.16b", diff --git a/unittests/InstructionCountCI/FlagM/VEX_map1.json b/unittests/InstructionCountCI/FlagM/VEX_map1.json index bce4ae222..baf975e07 100644 --- a/unittests/InstructionCountCI/FlagM/VEX_map1.json +++ b/unittests/InstructionCountCI/FlagM/VEX_map1.json @@ -72,7 +72,7 @@ "Map 1 0b01 0xd7 256-bit" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2208]", + "ldr q2, [x28, #2224]", "cmlt v3.16b, v16.16b, #0", "and v2.16b, v3.16b, v2.16b", "addp v2.16b, v2.16b, v2.16b", diff --git a/unittests/InstructionCountCI/H0F38.json b/unittests/InstructionCountCI/H0F38.json index 2b8e180cd..65009d764 100644 --- a/unittests/InstructionCountCI/H0F38.json +++ b/unittests/InstructionCountCI/H0F38.json @@ -624,7 +624,7 @@ "0x66 0x0f 0x38 0x41" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #1984]", + "ldr q2, [x28, #2000]", "zip1 v3.8h, v2.8h, v17.8h", "zip2 v2.8h, v2.8h, v17.8h", "umin v2.4s, v3.4s, v2.4s", diff --git a/unittests/InstructionCountCI/H0F3A.json b/unittests/InstructionCountCI/H0F3A.json index 6411205ce..6e720a585 100644 --- a/unittests/InstructionCountCI/H0F3A.json +++ b/unittests/InstructionCountCI/H0F3A.json @@ -315,7 +315,7 @@ "0x66 0x0f 0x3a 0x0c" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2112]", + "ldr q2, [x28, #2128]", "tbx v16.16b, {v17.16b}, v2.16b" ] }, @@ -325,7 +325,7 @@ "0x66 0x0f 0x3a 0x0c" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2128]", + "ldr q2, [x28, #2144]", "tbx v16.16b, {v17.16b}, v2.16b" ] }, @@ -344,7 +344,7 @@ "0x66 0x0f 0x3a 0x0c" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2144]", + "ldr q2, [x28, #2160]", "tbx v16.16b, {v17.16b}, v2.16b" ] }, @@ -364,7 +364,7 @@ "0x66 0x0f 0x3a 0x0c" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2160]", + "ldr q2, [x28, #2176]", "tbx v16.16b, {v17.16b}, v2.16b" ] }, @@ -383,7 +383,7 @@ "0x66 0x0f 0x3a 0x0c" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2176]", + "ldr q2, [x28, #2192]", "tbx v16.16b, {v17.16b}, v2.16b" ] }, @@ -393,7 +393,7 @@ "0x66 0x0f 0x3a 0x0c" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2192]", + "ldr q2, [x28, #2208]", "tbx v16.16b, {v17.16b}, v2.16b" ] }, diff --git a/unittests/InstructionCountCI/PrimaryGroup.json b/unittests/InstructionCountCI/PrimaryGroup.json index 34a173849..66426ee8c 100644 --- a/unittests/InstructionCountCI/PrimaryGroup.json +++ b/unittests/InstructionCountCI/PrimaryGroup.json @@ -2909,7 +2909,7 @@ "mov x0, x6", "mov x1, x20", "mov x2, x7", - "ldr x3, [x28, #2272]", + "ldr x3, [x28, #2288]", "str x30, [sp, #-16]!", "blr x3", "ldr x30, [sp], #16", @@ -2920,7 +2920,7 @@ "mov x0, x6", "mov x1, x20", "mov x2, x7", - "ldr x3, [x28, #2288]", + "ldr x3, [x28, #2304]", "str x30, [sp, #-16]!", "blr x3", "ldr x30, [sp], #16", @@ -2981,7 +2981,7 @@ "mov x0, x6", "mov x1, x20", "mov x2, x7", - "ldr x3, [x28, #2280]", + "ldr x3, [x28, #2296]", "str x30, [sp, #-16]!", "blr x3", "ldr x30, [sp], #16", @@ -2994,7 +2994,7 @@ "mov x0, x6", "mov x1, x20", "mov x2, x7", - "ldr x3, [x28, #2296]", + "ldr x3, [x28, #2312]", "str x30, [sp, #-16]!", "blr x3", "ldr x30, [sp], #16", diff --git a/unittests/InstructionCountCI/Secondary.json b/unittests/InstructionCountCI/Secondary.json index c86597fad..a43162e42 100644 --- a/unittests/InstructionCountCI/Secondary.json +++ b/unittests/InstructionCountCI/Secondary.json @@ -646,7 +646,7 @@ "Comment": "0x0f 0x50", "ExpectedArm64ASM": [ "ushr v2.4s, v16.4s, #31", - "ldr q3, [x28, #2080]", + "ldr q3, [x28, #2096]", "ushl v2.4s, v2.4s, v3.4s", "addv s2, v2.4s", "mov w4, v2.s[0]" @@ -657,7 +657,7 @@ "Comment": "0x0f 0x50", "ExpectedArm64ASM": [ "ushr v2.4s, v16.4s, #31", - "ldr q3, [x28, #2080]", + "ldr q3, [x28, #2096]", "ushl v2.4s, v2.4s, v3.4s", "addv s2, v2.4s", "mov w4, v2.s[0]" @@ -3434,7 +3434,7 @@ "Comment": "0x0f 0xd7", "ExpectedArm64ASM": [ "ldr d2, [x28, #768]", - "ldr d3, [x28, #2208]", + "ldr d3, [x28, #2224]", "cmlt v2.16b, v2.16b, #0", "and v2.16b, v2.16b, v3.16b", "addp v2.16b, v2.16b, v2.16b", diff --git a/unittests/InstructionCountCI/Secondary_OpSize.json b/unittests/InstructionCountCI/Secondary_OpSize.json index cf4efd120..f60bf4613 100644 --- a/unittests/InstructionCountCI/Secondary_OpSize.json +++ b/unittests/InstructionCountCI/Secondary_OpSize.json @@ -1014,7 +1014,7 @@ "ExpectedInstructionCount": 3, "Comment": "0x66 0x0f 0xd0", "ExpectedArm64ASM": [ - "ldr q2, [x28, #2048]", + "ldr q2, [x28, #2064]", "eor v2.16b, v17.16b, v2.16b", "fadd v16.2d, v16.2d, v2.2d" ] @@ -1070,7 +1070,7 @@ "ExpectedInstructionCount": 7, "Comment": "0x66 0x0f 0xd7", "ExpectedArm64ASM": [ - "ldr q2, [x28, #2208]", + "ldr q2, [x28, #2224]", "cmlt v3.16b, v16.16b, #0", "and v2.16b, v3.16b, v2.16b", "addp v2.16b, v2.16b, v2.16b", diff --git a/unittests/InstructionCountCI/Secondary_REPNE.json b/unittests/InstructionCountCI/Secondary_REPNE.json index 01de2bdc1..d7280457c 100644 --- a/unittests/InstructionCountCI/Secondary_REPNE.json +++ b/unittests/InstructionCountCI/Secondary_REPNE.json @@ -452,7 +452,7 @@ "ExpectedInstructionCount": 3, "Comment": "0xf2 0x0f 0xd0", "ExpectedArm64ASM": [ - "ldr q2, [x28, #2016]", + "ldr q2, [x28, #2032]", "eor v2.16b, v17.16b, v2.16b", "fadd v16.4s, v16.4s, v2.4s" ] diff --git a/unittests/InstructionCountCI/VEX_map1.json b/unittests/InstructionCountCI/VEX_map1.json index e1195c29c..06f1f4dcc 100644 --- a/unittests/InstructionCountCI/VEX_map1.json +++ b/unittests/InstructionCountCI/VEX_map1.json @@ -4338,7 +4338,7 @@ "Map 1 0b01 0xd0 128-bit" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2048]", + "ldr q2, [x28, #2064]", "eor v2.16b, v18.16b, v2.16b", "fadd v16.2d, v17.2d, v2.2d" ] @@ -4361,7 +4361,7 @@ "Map 1 0b11 0xd0 128-bit" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2016]", + "ldr q2, [x28, #2032]", "eor v2.16b, v18.16b, v2.16b", "fadd v16.4s, v17.4s, v2.4s" ] @@ -4498,7 +4498,7 @@ "Map 1 0b01 0xd7 256-bit" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2208]", + "ldr q2, [x28, #2224]", "cmlt v3.16b, v16.16b, #0", "and v2.16b, v3.16b, v2.16b", "addp v2.16b, v2.16b, v2.16b", diff --git a/unittests/InstructionCountCI/VEX_map2.json b/unittests/InstructionCountCI/VEX_map2.json index e98447f87..dd6c29180 100644 --- a/unittests/InstructionCountCI/VEX_map2.json +++ b/unittests/InstructionCountCI/VEX_map2.json @@ -1575,7 +1575,7 @@ "Map 2 0b01 0x41 256-bit" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #1984]", + "ldr q2, [x28, #2000]", "zip1 v3.8h, v2.8h, v17.8h", "zip2 v2.8h, v2.8h, v17.8h", "umin v2.4s, v3.4s, v2.4s", diff --git a/unittests/InstructionCountCI/VEX_map3.json b/unittests/InstructionCountCI/VEX_map3.json index 57330e2cb..bcb21cc5c 100644 --- a/unittests/InstructionCountCI/VEX_map3.json +++ b/unittests/InstructionCountCI/VEX_map3.json @@ -4799,7 +4799,7 @@ "Map 3 0b01 0xdf 128-bit" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2096]", + "ldr q2, [x28, #2112]", "movi v3.2d, #0x0", "mov v16.16b, v17.16b", "unimplemented (Unimplemented)", @@ -4812,7 +4812,7 @@ "Map 3 0b01 0xdf 128-bit" ], "ExpectedArm64ASM": [ - "ldr q2, [x28, #2096]", + "ldr q2, [x28, #2112]", "movi v3.2d, #0x0", "mov v16.16b, v17.16b", "unimplemented (Unimplemented)",