VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Crypto
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2017-06-26 22:52:59 (GMT)
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2017-06-26 22:55:25 (GMT)
commiteebb2773745bcedf12ec79607495344781367f2a (patch)
tree7743bab782d9b2cb2edb65d997904cb3ffd573cc /src/Crypto
parent79cb3af526e0c1c26f24e0199239e4a1e06d5415 (diff)
downloadVeraCrypt-eebb2773745bcedf12ec79607495344781367f2a.zip
VeraCrypt-eebb2773745bcedf12ec79607495344781367f2a.tar.gz
Enable AVX assembly instructions only when the OS implements AVX support
Diffstat (limited to 'src/Crypto')
-rw-r--r--src/Crypto/cpu.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c
index 5c74eca..a9c6e92 100644
--- a/src/Crypto/cpu.c
+++ b/src/Crypto/cpu.c
@@ -187,6 +187,19 @@ static int TrySSE2()
#endif
}
+static uint64 xgetbv()
+{
+#if defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) && !defined(_UEFI)
+ return _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
+#elif defined(__GNUC__) || defined(__clang__)
+ uint32 eax, edx;
+ __asm__ __volatile__(".byte 0x0F, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0));
+ return ((uint64_t)edx << 32) | eax;
+#else
+ return 0;
+#endif
+}
+
int g_x86DetectionDone = 0;
int g_hasISSE = 0, g_hasSSE2 = 0, g_hasSSSE3 = 0, g_hasMMX = 0, g_hasAESNI = 0, g_hasCLMUL = 0, g_isP4 = 0;
int g_hasAVX = 0, g_hasAVX2 = 0, g_hasBMI2 = 0, g_hasSSE42 = 0, g_hasSSE41 = 0, g_isIntel = 0, g_isAMD = 0;
@@ -292,9 +305,13 @@ void DetectX86Features()
g_hasMMX = (cpuid1[3] & (1 << 23)) != 0;
if ((cpuid1[3] & (1 << 26)) != 0)
g_hasSSE2 = TrySSE2();
- g_hasAVX2 = g_hasSSE2 && (cpuid1[1] & (1 << 5));
+ if (g_hasSSE2 && (cpuid1[2] & (1 << 28)) && (cpuid1[2] & (1 << 27))) /* CPU has AVX and OS supports XSAVE/XRSTORE */
+ {
+ uint64 xcrFeatureMask = xgetbv();
+ g_hasAVX = (xcrFeatureMask & 0x6) == 0x6;
+ }
+ g_hasAVX2 = g_hasAVX && (cpuid1[1] & (1 << 5));
g_hasBMI2 = g_hasSSE2 && (cpuid1[1] & (1 << 8));
- g_hasAVX = g_hasSSE2 && (cpuid1[2] & (1 << 28));
g_hasSSE42 = g_hasSSE2 && (cpuid1[2] & (1 << 20));
g_hasSSE41 = g_hasSSE2 && (cpuid1[2] & (1 << 19));
g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9));