|
From: Jeffrey W. <nol...@gm...> - 2014-02-10 23:36:05
|
I've got some code that determines CPU capabilities for x86 processors. I'm interested in RDRAND and AESNI, and I use three functions to determine the capabilities: HasIntel(), HasAESNI() and HasRDRAND(). Debug configurations compiled with GCC and Clang work fine. Release configuration compiled with GCC and Clang work fine. However, I get *one* incorrect result when running under Valgrind. The incorrect result is from HasRDRAND(). Under Valgrind, the result is 0, which means RDRAND is not available. I think its related to "Valgrind shows different results for ubuntu and debian x86 cpuid implementations", http://sourceforge.net/mailarchive/message.php?msg_id=31873412. Can anyone confirm this is related to VEX virtual machine? I want to ensure I'm not seeing success in Debug and Release by dumb-luck (and possibly have an unforeseen problem to fix). Thanks in advance. ********** # Debian 7.3, x64, fully patched $ uname -a Linux debian-q500 3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64 GNU/Linux # Built from sources a couple of weeks ago $ valgrind --version valgrind-3.9.0 ********** static void get_cpuid_info(CPUIDinfo *info, const unsigned int func, const unsigned int subfunc) { LogDebug("get_cpuid_info"); UNUSED(info); UNUSED(func); UNUSED(subfunc); __asm__ __volatile__ ( "cpuid" : "=a"(info->EAX), "=b"(info->EBX), "=c"(info->ECX), "=d"(info->EDX) : "a"(func), "c"(subfunc) ); } int HasIntel() { static int intel_cpu = 0; static once_flag flag; call_once(flag, []() { CPUIDinfo info; get_cpuid_info(&info,0,0); if(memcmp((char *)(&info.EBX), "Genu", 4) == 0 && memcmp((char *)(&info.EDX), "ineI", 4) == 0 && memcmp((char *)(&info.ECX), "ntel", 4) == 0) { intel_cpu = 1; } }); return intel_cpu; } int HasRDRAND() { static volatile int has_rdrand = 0; static once_flag flag; call_once(flag, []() { if(HasIntel()) { CPUIDinfo info; static const unsigned int RDRAND_CAP_BIT = (1 << 30); AC_ASSERT(0x40000000 == RDRAND_CAP_BIT); get_cpuid_info(&info,1,0); if ((info.ECX & RDRAND_CAP_BIT)==RDRAND_CAP_BIT) has_rdrand = 1; } }); return has_rdrand; } int HasAESNI() { static volatile int has_aesni = 0; static once_flag flag; call_once(flag, []() { if(HasIntel()) { CPUIDinfo info; static const unsigned int AESNI_CAP_BIT = (1 << 25); AC_ASSERT(0x2000000 == AESNI_CAP_BIT); get_cpuid_info(&info,1,0); if ((info.ECX & AESNI_CAP_BIT)==AESNI_CAP_BIT) has_aesni = 1; } }); return has_aesni; } |
|
From: John R. <jr...@Bi...> - 2014-02-11 03:43:14
|
On 02/10/2014 03:35 PM, Jeffrey Walton wrote: > I've got some code that determines CPU capabilities for x86 > processors. I'm interested in RDRAND and AESNI, and I use three > functions to determine the capabilities: HasIntel(), HasAESNI() and > HasRDRAND(). > > Debug configurations compiled with GCC and Clang work fine. Release > configuration compiled with GCC and Clang work fine. > > However, I get *one* incorrect result when running under Valgrind. The > incorrect result is from HasRDRAND(). Under Valgrind, the result is 0, > which means RDRAND is not available. Valgrind deliberately "fakes" the results of CPUID so that the bits reflect the virtual machine that valgrind knows how to support. Valgrind does not know how to implement RDRAND. [Only Intel and very few others know *exactly* what RDRAND does.] A quick search of the web for "valgrind CPUID" will fill in the details. It's even documented: search for 'CPUID' or 'SSE2' in and below the docs/ directory of the source tree. -- |
|
From: Jeffrey W. <nol...@gm...> - 2014-02-11 08:38:53
|
Thanks John. > A quick search of the web for "valgrind CPUID" will fill in the details. For https://bugs.kde.org/show_bug.cgi?id=155528, does Valgrind want the output for an i5 so it can fake an i5? I use Ivy Bridge i5's specifically for AES-NI and RDRAND. Perhpas a --cpu=XXX switch would be helpful for switching between cpu's. (Forgive me if its non-trivial to do. I know nothing about Valgrind architecture or operation. I just know a bit about using it to hunt leaks). Jeff On Mon, Feb 10, 2014 at 10:43 PM, John Reiser <jr...@bi...> wrote: > On 02/10/2014 03:35 PM, Jeffrey Walton wrote: >> I've got some code that determines CPU capabilities for x86 >> processors. I'm interested in RDRAND and AESNI, and I use three >> functions to determine the capabilities: HasIntel(), HasAESNI() and >> HasRDRAND(). >> >> Debug configurations compiled with GCC and Clang work fine. Release >> configuration compiled with GCC and Clang work fine. >> >> However, I get *one* incorrect result when running under Valgrind. The >> incorrect result is from HasRDRAND(). Under Valgrind, the result is 0, >> which means RDRAND is not available. > > Valgrind deliberately "fakes" the results of CPUID so that the bits > reflect the virtual machine that valgrind knows how to support. > Valgrind does not know how to implement RDRAND. > [Only Intel and very few others know *exactly* what RDRAND does.] > A quick search of the web for "valgrind CPUID" will fill in the details. > It's even documented: search for 'CPUID' or 'SSE2' in and below > the docs/ directory of the source tree. > |
|
From: Tom H. <to...@co...> - 2014-02-11 09:12:03
|
On 11/02/14 08:38, Jeffrey Walton wrote: > Perhpas a --cpu=XXX switch would be helpful for switching between > cpu's. (Forgive me if its non-trivial to do. I know nothing about > Valgrind architecture or operation. I just know a bit about using it > to hunt leaks). There's no point us allowing you to request a CPUID that reports RDRAND support if valgrind is going to bomb out with an unsupported instruction error as soon as you try and execute it. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: Jeffrey W. <nol...@gm...> - 2014-02-11 09:45:26
|
On Tue, Feb 11, 2014 at 4:11 AM, Tom Hughes <to...@co...> wrote: > On 11/02/14 08:38, Jeffrey Walton wrote: > >> Perhpas a --cpu=XXX switch would be helpful for switching between >> cpu's. (Forgive me if its non-trivial to do. I know nothing about >> Valgrind architecture or operation. I just know a bit about using it >> to hunt leaks). > > > There's no point us allowing you to request a CPUID that reports RDRAND > support if valgrind is going to bomb out with an unsupported instruction > error as soon as you try and execute it. > RDRAND is easy - back it with /dev/urand. AES-NI seems to be the difficult one, and I'm surprised Valgrind reports its supported. Jeff |
|
From: Tom H. <to...@co...> - 2014-02-11 09:50:46
|
On 11/02/14 09:45, Jeffrey Walton wrote: > On Tue, Feb 11, 2014 at 4:11 AM, Tom Hughes <to...@co...> wrote: >> On 11/02/14 08:38, Jeffrey Walton wrote: >> >>> Perhpas a --cpu=XXX switch would be helpful for switching between >>> cpu's. (Forgive me if its non-trivial to do. I know nothing about >>> Valgrind architecture or operation. I just know a bit about using it >>> to hunt leaks). >> >> >> There's no point us allowing you to request a CPUID that reports RDRAND >> support if valgrind is going to bomb out with an unsupported instruction >> error as soon as you try and execute it. > RDRAND is easy - back it with /dev/urand. I wasn't saying it couldn't be implemented, just that it's not as simple as just changing what CPUID reports, which seemed to be what you were suggesting. If we supported RDRAND then we would just announce it in CPUID and you wouldn't need a --cpu flag. > AES-NI seems to be the difficult one, and I'm surprised Valgrind > reports its supported. It's probably done via a helper so it effectively gets passed through. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |