mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-06-18 02:26:07 -05:00
Fix leaf 7 feature detection
BMI2 support is advertised by CPUID leaf 7, subleaf 0, EBX bit 8. The previous early assignment used CPUID leaf 1 EBX bit 8, which is not the BMI2 feature bit and could leave a bogus fallback value before vendor-specific leaf 7 detection. Keep BMI2 detection based on the leaf 7 result only. Unlike AVX2, BMI2 is GPR-only and does not require an OS/XCR0 state gate. Also save the max basic CPUID leaf immediately after CPUID leaf 0. The AMD/Hygon path reuses the cpuid buffer for leaf 0x80000005 before checking whether leaf 7 is available, so using the saved max basic leaf prevents RDSEED, AVX2, and BMI2 detection from being skipped because that buffer was clobbered.
This commit is contained in:
+9
-5
@@ -326,9 +326,12 @@ static BOOL CheckSHA256Support() {
|
|||||||
void DetectX86Features()
|
void DetectX86Features()
|
||||||
{
|
{
|
||||||
uint32 cpuid[4] = {0}, cpuid1[4] = {0}, cpuid2[4] = {0};
|
uint32 cpuid[4] = {0}, cpuid1[4] = {0}, cpuid2[4] = {0};
|
||||||
|
uint32 max_basic_leaf;
|
||||||
int leaf7_avx2 = 0;
|
int leaf7_avx2 = 0;
|
||||||
|
int leaf7_bmi2 = 0;
|
||||||
if (!CpuId(0, cpuid))
|
if (!CpuId(0, cpuid))
|
||||||
return;
|
return;
|
||||||
|
max_basic_leaf = cpuid[0];
|
||||||
if (!CpuId(1, cpuid1))
|
if (!CpuId(1, cpuid1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -344,7 +347,7 @@ void DetectX86Features()
|
|||||||
g_hasAVX = (xcrFeatureMask & 0x6) == 0x6;
|
g_hasAVX = (xcrFeatureMask & 0x6) == 0x6;
|
||||||
}
|
}
|
||||||
g_hasAVX2 = 0;
|
g_hasAVX2 = 0;
|
||||||
g_hasBMI2 = g_hasSSE2 && (cpuid1[1] & (1 << 8));
|
g_hasBMI2 = 0;
|
||||||
g_hasSSE42 = g_hasSSE2 && (cpuid1[2] & (1 << 20));
|
g_hasSSE42 = g_hasSSE2 && (cpuid1[2] & (1 << 20));
|
||||||
g_hasSSE41 = g_hasSSE2 && (cpuid1[2] & (1 << 19));
|
g_hasSSE41 = g_hasSSE2 && (cpuid1[2] & (1 << 19));
|
||||||
g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9));
|
g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9));
|
||||||
@@ -389,13 +392,13 @@ void DetectX86Features()
|
|||||||
g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
|
g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1);
|
||||||
g_hasRDRAND = (cpuid1[2] & (1 << 30)) != 0;
|
g_hasRDRAND = (cpuid1[2] & (1 << 30)) != 0;
|
||||||
|
|
||||||
if (cpuid[0] >= 7)
|
if (max_basic_leaf >= 7)
|
||||||
{
|
{
|
||||||
if (CpuId(7, cpuid2))
|
if (CpuId(7, cpuid2))
|
||||||
{
|
{
|
||||||
g_hasRDSEED = (cpuid2[1] & (1 << 18)) != 0;
|
g_hasRDSEED = (cpuid2[1] & (1 << 18)) != 0;
|
||||||
leaf7_avx2 = (cpuid2[1] & (1 << 5)) != 0;
|
leaf7_avx2 = (cpuid2[1] & (1 << 5)) != 0;
|
||||||
g_hasBMI2 = (cpuid2[1] & (1 << 8)) != 0;
|
leaf7_bmi2 = (cpuid2[1] & (1 << 8)) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -406,17 +409,18 @@ void DetectX86Features()
|
|||||||
g_cacheLineSize = GETBYTE(cpuid[2], 0);
|
g_cacheLineSize = GETBYTE(cpuid[2], 0);
|
||||||
g_hasRDRAND = (cpuid1[2] & (1 << 30)) != 0;
|
g_hasRDRAND = (cpuid1[2] & (1 << 30)) != 0;
|
||||||
|
|
||||||
if (cpuid[0] >= 7)
|
if (max_basic_leaf >= 7)
|
||||||
{
|
{
|
||||||
if (CpuId(7, cpuid2))
|
if (CpuId(7, cpuid2))
|
||||||
{
|
{
|
||||||
g_hasRDSEED = (cpuid2[1] & (1 << 18)) != 0;
|
g_hasRDSEED = (cpuid2[1] & (1 << 18)) != 0;
|
||||||
leaf7_avx2 = (cpuid2[1] & (1 << 5)) != 0;
|
leaf7_avx2 = (cpuid2[1] & (1 << 5)) != 0;
|
||||||
g_hasBMI2 = (cpuid2[1] & (1 << 8)) != 0;
|
leaf7_bmi2 = (cpuid2[1] & (1 << 8)) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_hasAVX2 = g_hasAVX && leaf7_avx2;
|
g_hasAVX2 = g_hasAVX && leaf7_avx2;
|
||||||
|
g_hasBMI2 = leaf7_bmi2;
|
||||||
#if defined(_MSC_VER) && !defined(_UEFI)
|
#if defined(_MSC_VER) && !defined(_UEFI)
|
||||||
/* Add check fur buggy RDRAND (AMD Ryzen case) even if we always use RDSEED instead of RDRAND when RDSEED available */
|
/* Add check fur buggy RDRAND (AMD Ryzen case) even if we always use RDSEED instead of RDRAND when RDSEED available */
|
||||||
if (g_hasRDRAND)
|
if (g_hasRDRAND)
|
||||||
|
|||||||
Reference in New Issue
Block a user