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;
}

------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk
_______________________________________________
Valgrind-users mailing list
Valgrind-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-users

Reply via email to