From 13c292263741705e06bf2d8d2c6e101bab30bb3f Mon Sep 17 00:00:00 2001 From: mayeut Date: Sun, 23 Oct 2016 20:22:26 +0200 Subject: [PATCH] Fix AVX/AVX2 runtime detection XSAVE_XRSTORE/AVX2/AVX bits were checked after a CPUID.(EAX=07H, ECX=0H) call. Only AVX2 flag shall be checked after that call. Check for XSAVE_XRSTORE/AVX shall be done after a CPUID.(EAX=01H, ECX=0H) call. --- lib/codec_choose.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/codec_choose.c b/lib/codec_choose.c index 0180aa5f..17e4d3a8 100644 --- a/lib/codec_choose.c +++ b/lib/codec_choose.c @@ -181,21 +181,24 @@ codec_choose_x86 (struct codec *codec) // // Note that XGETBV is only available on 686 or later CPUs, so the // instruction needs to be conditionally run. - if (max_level >= 7) { - __cpuid_count(7, 0, eax, ebx, ecx, edx); - + if (max_level >= 1) { + __cpuid_count(1, 0, eax, ebx, ecx, edx); if (ecx & bit_XSAVE_XRSTORE) { uint64_t xcr_mask; xcr_mask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); if (xcr_mask & _XCR_XMM_AND_YMM_STATE_ENABLED_BY_OS) { #if HAVE_AVX2 - if (ebx & bit_AVX2) { - codec->enc = base64_stream_encode_avx2; - codec->dec = base64_stream_decode_avx2; - return true; + if (max_level >= 7) { + __cpuid_count(7, 0, eax, ebx, ecx, edx); + if (ebx & bit_AVX2) { + codec->enc = base64_stream_encode_avx2; + codec->dec = base64_stream_decode_avx2; + return true; + } } #endif #if HAVE_AVX + __cpuid_count(1, 0, eax, ebx, ecx, edx); if (ecx & bit_AVX) { codec->enc = base64_stream_encode_avx; codec->dec = base64_stream_decode_avx;