From: Iain Buclaw Date: Tue, 7 Nov 2023 13:04:07 +0000 (+0100) Subject: libphobos: Fix regression d21 loops in getCpuInfo0B in Solaris/x86 kernel zone X-Git-Tag: releases/gcc-11.5.0~492 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=47d833394a09068ba0607a57aa149dfe3dc11e8b;p=thirdparty%2Fgcc.git libphobos: Fix regression d21 loops in getCpuInfo0B in Solaris/x86 kernel zone This function assumes that cpuid would return "invalid domain" when a sub-leaf index greater than what's supported is requested. This turned out not to always be the case when running on some virtual machines. As the loop only does anything for levels 0 and 1, make that a hard limit for number of times the loop is ran. PR d/112408 libphobos/ChangeLog: * libdruntime/core/cpuid.d (getCpuInfo0B): Limit number of times loop runs. (cherry picked from commit 0b25c1295d4e84af681f4b1f4af2ad37cd270da3) --- diff --git a/libphobos/libdruntime/core/cpuid.d b/libphobos/libdruntime/core/cpuid.d index e31f776d7eec..b05db248b816 100644 --- a/libphobos/libdruntime/core/cpuid.d +++ b/libphobos/libdruntime/core/cpuid.d @@ -651,10 +651,12 @@ void getAMDcacheinfo() // to determine number of processors. void getCpuInfo0B() { - int level=0; int threadsPerCore; uint a, b, c, d; - do { + // I'm not sure about this. The docs state that there + // are 2 hyperthreads per core if HT is factory enabled. + for (int level = 0; level < 2; level++) + { version (GNU_OR_LDC) asm pure nothrow @nogc { "cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (0x0B), "c" (level); } else asm pure nothrow @nogc { @@ -666,19 +668,20 @@ void getCpuInfo0B() mov c, ECX; mov d, EDX; } - if (b!=0) { - // I'm not sure about this. The docs state that there - // are 2 hyperthreads per core if HT is factory enabled. - if (level==0) + if (b != 0) + { + if (level == 0) threadsPerCore = b & 0xFFFF; - else if (level==1) { + else if (level == 1) + { cpuFeatures.maxThreads = b & 0xFFFF; cpuFeatures.maxCores = cpuFeatures.maxThreads / threadsPerCore; } - } - ++level; - } while (a!=0 || b!=0); + // Got "invalid domain" returned from cpuid + if (a == 0 && b == 0) + break; + } } void cpuidX86()