File leancrypto_avx_detect1.patch of Package leancrypto
commit 38bb12a185b2d3aa4ff3656d743b33b3ae25bac7
Author: Stephan Mueller <smueller@chronox.de>
Date: Tue Nov 25 22:40:25 2025 +0100
AVX2/512: properly detect support
Intel defines a specific check approach to detect AVX2/512 support.
This fixes when booting Linux with noxsave where AVX2/512 is not
available.
Reported-by: Alexander Sosedkin
Signed-off-by: Stephan Mueller <smueller@chronox.de>
Index: leancrypto-1.6.0/internal/src/cpufeatures_x86.c
===================================================================
--- leancrypto-1.6.0.orig/internal/src/cpufeatures_x86.c
+++ leancrypto-1.6.0/internal/src/cpufeatures_x86.c
@@ -37,12 +37,22 @@
/* Leaf 1 */
#define LC_INTEL_AESNI_ECX (1 << 25)
#define LC_INTEL_AVX_ECX (1 << 28)
+#define LC_INTEL_FMA_ECX (1 << 12)
+#define LC_INTEL_MOVBE_ECX (1 << 22)
+#define LC_INTEL_OSXSAVE (1 << 27)
+#define LC_INTEL_AVX_PREREQ1 \
+ (LC_INTEL_FMA_ECX | LC_INTEL_MOVBE_ECX | LC_INTEL_OSXSAVE)
/* Leaf 7, subleaf 0 of CPUID */
#define LC_INTEL_AVX2_EBX (1 << 5)
+#define LC_INTEL_BMI1_EBX (1 << 3)
+#define LC_INTEL_BMI2_EBX (1 << 8)
+#define LC_INTEL_AVX2_PREREQ2 \
+ (LC_INTEL_AVX2_EBX | LC_INTEL_BMI1_EBX | LC_INTEL_BMI2_EBX)
#define LC_INTEL_AVX512F_EBX (1 << 16)
#define LC_INTEL_VPCLMUL_ECX (1 << 10)
#define LC_INTEL_PCLMUL_ECX (1 << 1)
#define LC_INTEL_SHANI_EBX (1 << 29)
+#define LC_INTEL_SHANI_EBX (1 << 29)
#define LC_INTEL_SHANI512_EAX (1 << 0)
/* This is required by aes_aesni_x86_64.S */
@@ -111,11 +121,30 @@ LC_INTERFACE_FUNCTION(enum lc_cpu_featur
/* read advanced features eax = 7, ecx = 0 */
cpuid_eax_ecx(7, 0, eax, ebx, ecx, edx);
- if (ebx & LC_INTEL_AVX2_EBX)
- feat |= LC_CPU_FEATURE_INTEL_AVX2;
- if (ebx & LC_INTEL_AVX512F_EBX)
- feat |= LC_CPU_FEATURE_INTEL_AVX512;
+ /*
+ * Check AVX2 support according to Intel document "How to detect New
+ * Instruction support in the 4th generation Intel® Core™ processor
+ * family"
+ */
+ if ((x86_64_cpuid[2] & LC_INTEL_AVX_PREREQ1) == LC_INTEL_AVX_PREREQ1) {
+ uint32_t xcr0;
+
+#if defined(_MSC_VER) && !defined(__clang__)
+ xcr0 = _xgetbv(0);
+#else
+ __asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx");
+#endif
+ /* Check if xmm and ymm state are enabled in XCR0. */
+ if ((xcr0 & 6) == 6) {
+ if ((ebx & LC_INTEL_AVX2_PREREQ2) ==
+ LC_INTEL_AVX2_PREREQ2)
+ feat |= LC_CPU_FEATURE_INTEL_AVX2;
+
+ if (ebx & LC_INTEL_AVX512F_EBX)
+ feat |= LC_CPU_FEATURE_INTEL_AVX512;
+ }
+ }
if (ecx & LC_INTEL_VPCLMUL_ECX)
feat |= LC_CPU_FEATURE_INTEL_VPCLMUL;