ref: 03889ae76dea9c5e63e64df495fd77d613a03a80
parent: ccb42e05cc6eb98a15874b9695361025b3ee17ab
author: Timothy B. Terriberry <[email protected]>
date: Tue Jun 28 18:33:43 EDT 2022
Check the return value of __get_cpuid(). This function can fail if CPUID is not supported or the maximum supported value of EAX is less than the requested one. Check the return value and explicitly disable all SIMD if it does fail. This was happening before implicitly because of the initialization of info[] to zero, but being explicit about it makes it less likely someone will break this behavior because they did not realize what was going on.
--- a/celt/x86/x86cpu.c
+++ b/celt/x86/x86cpu.c
@@ -81,7 +81,12 @@
);
#endif
#elif defined(CPU_INFO_BY_C)
- __get_cpuid(InfoType, &(CPUInfo[0]), &(CPUInfo[1]), &(CPUInfo[2]), &(CPUInfo[3]));
+ if !(__get_cpuid(InfoType, &(CPUInfo[0]), &(CPUInfo[1]), &(CPUInfo[2]), &(CPUInfo[3]))) {
+ /* Our function cannot fail, but __get_cpuid can.
+ Returning all zeroes will effectively disable all SIMD, which is
+ what we want on CPUs that don't support CPUID. */
+ CPUInfo[3] = CPUInfo[2] = CPUInfo[1] = CPUInfo[0] = 0;
+ }
#endif
}
@@ -98,7 +103,7 @@
static void opus_cpu_feature_check(CPU_Feature *cpu_feature)
{
- unsigned int info[4] = {0};
+ unsigned int info[4];
unsigned int nIds = 0;
cpuid(info, 0);