Bug 353370 - RDRAND amd64->IR: unhandled instruction bytes: 0x48 0xF 0xC7 0xF0 0x72 0x4 0xFF 0xC9
Summary: RDRAND amd64->IR: unhandled instruction bytes: 0x48 0xF 0xC7 0xF0 0x72 0x4 0x...
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: vex (show other bugs)
Version: 3.10 SVN
Platform: Gentoo Packages Linux
: NOR grave
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
: 357873 358988 365325 375845 378180 381699 387940 395809 396176 400279 401846 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-09-30 13:06 UTC by Andrei Voropaev
Modified: 2019-05-30 11:25 UTC (History)
16 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
cpuinfo (8.03 KB, application/octet-stream)
2015-10-01 06:49 UTC, Andrei Voropaev
Details
hwcaps.3_10 (176 bytes, text/plain)
2015-10-01 06:49 UTC, Andrei Voropaev
Details
hwcaps.3_11 (178 bytes, text/plain)
2015-10-01 06:49 UTC, Andrei Voropaev
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrei Voropaev 2015-09-30 13:06:00 UTC
Newest version 3.11 stopped handling some instruction. Version 3.10 works without any problems. Version 3.11 aborts application with message

vex amd64->IR: unhandled instruction bytes: 0x48 0xF 0xC7 0xF0 0x72 0x4 0xFF 0xC9
vex amd64->IR:   REX=1 REX.W=1 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR:   VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=0F
vex amd64->IR:   PFX.66=0 PFX.F2=0 PFX.F3=0
==24113== valgrind: Unrecognised instruction at address 0x519ac23.
==24113==    at 0x519AC23: poll_drng.isra.0 (in /usr/lib64/libgcrypt.so.20.0.3)
==24113==    by 0x519AE6B: _gcry_rndlinux_gather_random (in /usr/lib64/libgcrypt.so.20.0.3)
==24113==    by 0x51981FF: read_random_source (in /usr/lib64/libgcrypt.so.20.0.3)
==24113==    by 0x51992AB: _gcry_rngcsprng_randomize (in /usr/lib64/libgcrypt.so.20.0.3)
==24113==    by 0x5198074: _gcry_create_nonce (in /usr/lib64/libgcrypt.so.20.0.3)
....



Reproducible: Always

Steps to Reproduce:
1. Start application that uses gcrypt under Valgrind 3.11
2.
3.

Actual Results:  
Valgrind fails to recognize instruction and issues SIGKILL

Expected Results:  
Valgrind runs without any complaints

I'm using gcc (Gentoo 4.8.5 p1.3, pie-0.6.2) 4.8.5 to compile binaries. The libraries are compiled with flags -march=native -O2 -pipe. My CPU model_name is Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Comment 1 Tom Hughes 2015-09-30 13:58:11 UTC
I suspect it's more likely that a change to the declared CPUID has caused your program to execute instructions it didn't try and execute before.

The instruction here is RDRAND but with a REX prefix that sets REX.W to get 64 bit operation.
Comment 2 Andrei Voropaev 2015-09-30 14:39:13 UTC
Hm. What do you mean with the "change to the declared CPUID"?
Definitely I didn't change anything except for Valgrind. If I revert
back to version 3.10 (which I did now) then things work. With version
3.11 Valgrind becomes unusable.

After all, I don't really care what is causing this problem. I just
would like to keep using newer versions of Valgrind and not get stuck
with old one :)

On Wed, Sep 30, 2015 at 3:58 PM, Tom Hughes <tom@compton.nu> wrote:
> https://bugs.kde.org/show_bug.cgi?id=353370
>
> Tom Hughes <tom@compton.nu> changed:
>
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                  CC|                            |tom@compton.nu
>
> --- Comment #1 from Tom Hughes <tom@compton.nu> ---
> I suspect it's more likely that a change to the declared CPUID has caused your
> program to execute instructions it didn't try and execute before.
>
> The instruction here is RDRAND but with a REX prefix that sets REX.W to get 64
> bit operation.
>
> --
> You are receiving this mail because:
> You reported the bug.
Comment 3 Tom Hughes 2015-09-30 14:54:25 UTC
I mean that valgrind has potentially changed the CPU features that it advertises to your program - because it is a virtualised CPU it advertises one of a small number of standard feature sets rather than what your CPU natively declares.
Comment 4 Florian Krohm 2015-09-30 15:25:30 UTC
Can you provide the following info:

(1) cat /proc/cpuinfo
(2) valgrind -d -v date 2> blah; grep hwcaps blah
      both for 3.10.x and 3.11.0
Comment 5 Andrei Voropaev 2015-10-01 06:49:06 UTC
Created attachment 94790 [details]
cpuinfo

On Wed, Sep 30, 2015 at 5:25 PM, Florian Krohm <florian@eich-krohm.de> wrote:
> valgrind -d -v date 2> blah; grep hwcaps blah

See attached.
Comment 6 Andrei Voropaev 2015-10-01 06:49:09 UTC
Created attachment 94791 [details]
hwcaps.3_10
Comment 7 Andrei Voropaev 2015-10-01 06:49:09 UTC
Created attachment 94792 [details]
hwcaps.3_11
Comment 8 Mark Wielaard 2015-10-01 09:27:15 UTC
We seem to advertise RDRAND in cpuid:

valgrind -q cpuid | grep RDRAND
      RDRAND instruction                      = true

But cannot find where we implement it.
Comment 9 Mark Wielaard 2015-10-01 09:40:44 UTC
Since we don't implement RDRAND we shouldn't advertise it. Does the following patch help?

diff --git a/priv/guest_amd64_helpers.c b/priv/guest_amd64_helpers.c
index e77d753..ab53e15 100644
--- a/priv/guest_amd64_helpers.c
+++ b/priv/guest_amd64_helpers.c
@@ -3101,7 +3101,8 @@ void amd64g_dirtyhelper_CPUID_avx2 ( VexGuestAMD64State* st )
          SET_ABCD(0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69);
          break;
       case 0x00000001:
-         SET_ABCD(0x000306c3, 0x02100800, 0x7ffafbff, 0xbfebfbff);
+         /* Don't advertise RDRAND support, bit 30 in ECX.  */
+         SET_ABCD(0x000306c3, 0x02100800, 0x3ffafbff, 0xbfebfbff);
          break;
       case 0x00000002:
          SET_ABCD(0x76036301, 0x00f0b6ff, 0x00000000, 0x00c10000);
Comment 10 Andrei Voropaev 2015-10-01 12:17:27 UTC
On Thu, Oct 1, 2015 at 11:40 AM, Mark Wielaard <mjw@redhat.com> wrote:
> guest_amd64_helpers.c


Yes. this patch fixes the problem.

Thank you
Comment 11 Mark Wielaard 2015-10-01 12:36:12 UTC
Thanks for reporting and checking.
Fix pushed as VEX svn r3197
Comment 12 Mark Wielaard 2016-01-12 14:45:36 UTC
*** Bug 357873 has been marked as a duplicate of this bug. ***
Comment 13 Tom Hughes 2016-02-04 16:34:28 UTC
*** Bug 358988 has been marked as a duplicate of this bug. ***
Comment 14 Julian Seward 2016-09-14 14:46:25 UTC
*** Bug 365325 has been marked as a duplicate of this bug. ***
Comment 15 Tom Hughes 2017-02-01 15:53:09 UTC
*** Bug 375845 has been marked as a duplicate of this bug. ***
Comment 16 Tom Hughes 2017-03-27 23:33:37 UTC
*** Bug 378180 has been marked as a duplicate of this bug. ***
Comment 17 Mark Wielaard 2017-06-26 22:38:50 UTC
*** Bug 381699 has been marked as a duplicate of this bug. ***
Comment 18 Tom Hughes 2018-04-18 11:30:48 UTC
*** Bug 387940 has been marked as a duplicate of this bug. ***
Comment 19 Mark Wielaard 2018-06-24 08:45:11 UTC
*** Bug 395809 has been marked as a duplicate of this bug. ***
Comment 20 Tom Hughes 2018-07-04 23:14:09 UTC
*** Bug 396176 has been marked as a duplicate of this bug. ***
Comment 21 Mark Wielaard 2018-10-25 17:34:33 UTC
*** Bug 400279 has been marked as a duplicate of this bug. ***
Comment 22 Mark Wielaard 2018-12-07 08:05:17 UTC
*** Bug 401846 has been marked as a duplicate of this bug. ***
Comment 23 Cyp 2019-05-28 11:11:00 UTC
I'm seeing this with valgrind-3.15.0, even though the release notes say RdRand is now supported.

The system is compiled with -march=native on an “Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz”.

--

$ valgrind scribus
==26338== Memcheck, a memory error detector
==26338== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==26338== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==26338== Command: scribus
==26338== 
vex amd64->IR: unhandled instruction bytes: 0xF 0xC7 0xF0 0xB9 0x1 0x0 0x0 0x0 0x89 0x3
vex amd64->IR:   REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR:   VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=0F
vex amd64->IR:   PFX.66=0 PFX.F2=0 PFX.F3=0
==26338== valgrind: Unrecognised instruction at address 0x8769603.
==26338==    at 0x8769603: _rdrand32_step (immintrin.h:138)
==26338==    by 0x8769603: qt_random_cpu (qrandom.cpp:114)
==26338==    by 0x8769603: QRandomGenerator::SystemGenerator::generate(unsigned int*, unsigned int*) (qrandom.cpp:370)
==26338==    by 0x87BC11A: fillRange<unsigned int> (qrandom.h:143)
==26338==    by 0x87BC11A: generate (qrandom.h:87)
==26338==    by 0x87BC11A: qt_create_qhash_seed() (qhash.cpp:299)
==26338==    by 0x87BC1D4: qt_initialize_qhash_seed (qhash.cpp:325)
==26338==    by 0x87BC1D4: qt_initialize_qhash_seed() (qhash.cpp:322)
==26338==    by 0x87BC7C9: QHashData::detach_helper(void (*)(QHashData::Node*, void*), void (*)(QHashData::Node*), int, int) (qhash.cpp:502)
==26338==    by 0x87CFDB9: QHash<QRegExpEngineKey, QCache<QRegExpEngineKey, QRegExpEngine>::Node>::detach_helper() [clone .isra.191] (qhash.h:599)
==26338==    by 0x87D5FFB: detach (qhash.h:275)
==26338==    by 0x87D5FFB: find (qhash.h:901)
==26338==    by 0x87D5FFB: take (qcache.h:154)
==26338==    by 0x87D5FFB: prepareEngine_helper(QRegExpPrivate*) (qregexp.cpp:3853)
…

--

http://www.valgrind.org/docs/manual/dist.news.html
Release 3.15.0 (12 April 2019)
* amd64 (x86_64): the RDRAND and F16C insn set extensions are now supported.
Comment 24 Tom Hughes 2019-05-28 11:56:22 UTC
That's badly written - they are not supported but this bug is resolved by making valgrind's emulation of the cpuid instruction remove the bit which claims support for them.

So an application which tests for rdrand before using it will now work but one which just assumes it can use it will still fail.
Comment 25 Tom Hughes 2019-05-28 12:08:27 UTC
So actually there is a later commit which does actually implement RDRAND but only  for AVX2 capable CPUs which yours is not. My other point remains correct, that we won't advertise RDRAND on any machine where we don't support it.

The reason by the way that we only do it for AVX2 capable CPUs is that we only support a limited set of CPU profiles and the next one down is:

  Intel(R) Core(TM) i5-2300 CPU @ 2.80GHz

which is not RDRAND capable.
Comment 26 Julian Seward 2019-05-28 12:11:04 UTC
(In reply to Tom Hughes from comment #25)
> So actually there is a later commit which does actually implement RDRAND but
> only  for AVX2 capable CPUs which yours is not.

I think Mark just fixed it to work on AVX-only capable CPUs too.  See
bug 408009.
Comment 27 Julian Seward 2019-05-28 12:13:11 UTC
That doesn't invalidate Tom's comment though: you should always test
with CPUID at run time for the presence of any particular instruction
set extension, before using it.  Especially for recent or obscure
extensions.
Comment 28 Tom Hughes 2019-05-28 13:31:50 UTC
That latest change isn't actually committed yet ;-)
Comment 29 Cyp 2019-05-30 11:25:06 UTC
It is now. And seems to work, thanks.