mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
fix: Update node's simdutf to 3.2.9 to fix AVX-related crashes (#40446)
Fix: Backport AVX detection fix from simdutf 3.2.9
simdutf < 3.2.9 contains a flawed detection routine to decide whether
AVX and/or AVX2 can be used. In most cases, it works good enough, but
in some corner cases (combination of specific CPU model, microcode
version, operating system and OS configuration), that flawed detection
results in simdutf trying to use AVX/AVX2 although the OS doesn't allow
its use (for example as a mitigation measure against the "gather data
sampling" vulnerability), which then crashes the application with an
illegal instruction error.
This fix is only needed for node < 18.17.0, because later versions use
a simdutf version > 3.2.9.
Cherry-picked and backported from 55b107f609
Signed-off-by: Pascal Ernster <git@hardfalcon.net>
Co-authored-by: Daniel Lemire <daniel@lemire.me>
Co-authored-by: easyaspi314 <easyaspi314@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This commit is contained in:
@@ -45,4 +45,5 @@ net_fix_crash_due_to_simultaneous_close_shutdown_on_js_stream.patch
|
||||
net_use_asserts_in_js_socket_stream_to_catch_races_in_future.patch
|
||||
lib_fix_broadcastchannel_initialization_location.patch
|
||||
win_process_avoid_assert_after_spawning_store_app_4152.patch
|
||||
fix_backport_avx_detection_fix_from_simdutf_3_2_9.patch
|
||||
fix_avx_detection.patch
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Lemire <daniel@lemire.me>
|
||||
Date: Fri, 12 May 2023 15:20:29 -0400
|
||||
Subject: Fix: Backport AVX detection fix from simdutf 3.2.9
|
||||
|
||||
simdutf < 3.2.9 contains a flawed detection routine to decide whether
|
||||
AVX and/or AVX2 can be used. In most cases, it works good enough, but
|
||||
in some corner cases (combination of specific CPU model, microcode
|
||||
version, operating system and OS configuration), that flawed detection
|
||||
results in simdutf trying to use AVX/AVX2 although the OS doesn't allow
|
||||
its use (for example as a mitigation measure against the "gather data
|
||||
sampling" vulnerability), which then crashes the application with an
|
||||
illegal instruction error.
|
||||
|
||||
This fix is only needed for node < 18.17.0, because later versions use
|
||||
a simdutf version > 3.2.9.
|
||||
|
||||
Cherry-picked and backported from https://github.com/simdutf/simdutf/commit/55b107f609f5f63880db650a92861ae84cb10abe
|
||||
|
||||
Co-authored-by: Daniel Lemire <daniel@lemire.me>
|
||||
Co-authored-by: easyaspi314 <easyaspi314@users.noreply.github.com>
|
||||
Signed-off-by: Pascal Ernster <git@hardfalcon.net>
|
||||
|
||||
diff --git a/deps/simdutf/simdutf.h b/deps/simdutf/simdutf.h
|
||||
index 80189d316cba8c9127b652da9e0bcb76d5b9eeb4..4e5ce1e26b6b803698e55436ce0c0ab358662c9e 100644
|
||||
--- a/deps/simdutf/simdutf.h
|
||||
+++ b/deps/simdutf/simdutf.h
|
||||
@@ -706,6 +706,7 @@ namespace cpuid_bit {
|
||||
// EAX = 0x01
|
||||
constexpr uint32_t pclmulqdq = uint32_t(1) << 1; ///< @private bit 1 of ECX for EAX=0x1
|
||||
constexpr uint32_t sse42 = uint32_t(1) << 20; ///< @private bit 20 of ECX for EAX=0x1
|
||||
+ constexpr uint32_t osxsave = (uint32_t(1) << 26) | (uint32_t(1) << 27); ///< @private bits 26+27 of ECX for EAX=0x1
|
||||
|
||||
// EAX = 0x7f (Structured Extended Feature Flags), ECX = 0x00 (Sub-leaf)
|
||||
// See: "Table 3-8. Information Returned by CPUID Instruction"
|
||||
@@ -731,6 +732,10 @@ namespace cpuid_bit {
|
||||
namespace edx {
|
||||
constexpr uint32_t avx512vp2intersect = uint32_t(1) << 8;
|
||||
}
|
||||
+ namespace xcr0_bit {
|
||||
+ constexpr uint64_t avx256_saved = uint64_t(1) << 2; ///< @private bit 2 = AVX
|
||||
+ constexpr uint64_t avx512_saved = uint64_t(7) << 5; ///< @private bits 5,6,7 = opmask, ZMM_hi256, hi16_ZMM
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,7 +745,7 @@ static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
|
||||
uint32_t *edx) {
|
||||
#if defined(_MSC_VER)
|
||||
int cpu_info[4];
|
||||
- __cpuid(cpu_info, *eax);
|
||||
+ __cpuidex(cpu_info, *eax, *ecx);
|
||||
*eax = cpu_info[0];
|
||||
*ebx = cpu_info[1];
|
||||
*ecx = cpu_info[2];
|
||||
@@ -758,6 +763,16 @@ static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
|
||||
#endif
|
||||
}
|
||||
|
||||
+static inline uint64_t xgetbv() {
|
||||
+ #if defined(_MSC_VER)
|
||||
+ return _xgetbv(0);
|
||||
+ #else
|
||||
+ uint32_t xcr0_lo, xcr0_hi;
|
||||
+ asm volatile("xgetbv\n\t" : "=a" (xcr0_lo), "=d" (xcr0_hi) : "c" (0));
|
||||
+ return xcr0_lo | ((uint64_t)xcr0_hi << 32);
|
||||
+ #endif
|
||||
+ }
|
||||
+
|
||||
static inline uint32_t detect_supported_architectures() {
|
||||
uint32_t eax;
|
||||
uint32_t ebx = 0;
|
||||
@@ -777,6 +792,16 @@ static inline uint32_t detect_supported_architectures() {
|
||||
host_isa |= instruction_set::PCLMULQDQ;
|
||||
}
|
||||
|
||||
+ if ((ecx & cpuid_bit::osxsave) != cpuid_bit::osxsave) {
|
||||
+ return host_isa;
|
||||
+ }
|
||||
+
|
||||
+ // xgetbv for checking if the OS saves registers
|
||||
+ uint64_t xcr0 = xgetbv();
|
||||
+
|
||||
+ if ((xcr0 & cpuid_bit::xcr0_bit::avx256_saved) == 0) {
|
||||
+ return host_isa;
|
||||
+ }
|
||||
// ECX for EAX=0x7
|
||||
eax = 0x7;
|
||||
ecx = 0x0; // Sub-leaf = 0
|
||||
@@ -790,6 +815,9 @@ static inline uint32_t detect_supported_architectures() {
|
||||
if (ebx & cpuid_bit::ebx::bmi2) {
|
||||
host_isa |= instruction_set::BMI2;
|
||||
}
|
||||
+ if (!((xcr0 & cpuid_bit::xcr0_bit::avx512_saved) == cpuid_bit::xcr0_bit::avx512_saved)) {
|
||||
+ return host_isa;
|
||||
+ }
|
||||
if (ebx & cpuid_bit::ebx::avx512f) {
|
||||
host_isa |= instruction_set::AVX512F;
|
||||
}
|
||||
Reference in New Issue
Block a user