diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-28 23:28:48 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-28 23:28:48 +0000 |
commit | 26ce2f689be5eb224ecef373e661d605cd039391 (patch) | |
tree | 25155afb29634d5f09f93e0859db55c824492f54 /base/cpu.cc | |
parent | 690e14d2713691766aa29fa2c470f8f1767ac07f (diff) | |
download | chromium_src-26ce2f689be5eb224ecef373e661d605cd039391.zip chromium_src-26ce2f689be5eb224ecef373e661d605cd039391.tar.gz chromium_src-26ce2f689be5eb224ecef373e661d605cd039391.tar.bz2 |
base: check XSAVE CPUID bit before xgetbv.
We follow Intel's example code for detecting whether AVX is supported by
the current CPU. However, we are seeing invalid instruction crashes
caused by the xgetbv instruction (see bug). I suspect these are caused
by VMs incorrectly emulating the CPU.
This change causes the code to additionally check the XSAVE bit in the
CPUID information. From the Intel documentation for CPUID:
"A value of 1 indicates that the processor supports the XSAVE/XRSTOR
processor extended states feature, the XSETBV/XGETBV instructions, and
XCR0."
Hopefully, if the VM doesn't support xgetbv, then it doesn't set this
bit.
BUG=375968
Review URL: https://codereview.chromium.org/306583002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273393 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/cpu.cc')
-rw-r--r-- | base/cpu.cc | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/base/cpu.cc b/base/cpu.cc index f18b8db..dcba3b6 100644 --- a/base/cpu.cc +++ b/base/cpu.cc @@ -183,8 +183,14 @@ void CPU::Initialize() { // b) XSAVE is supported by the CPU and // c) XSAVE is enabled by the kernel. // See http://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled + // + // In addition, we have observed some crashes with the xgetbv instruction + // even after following Intel's example code. (See crbug.com/375968.) + // Because of that, we also test the XSAVE bit because its description in + // the CPUID documentation suggests that it signals xgetbv support. has_avx_ = has_avx_hardware_ && + (cpu_info[2] & 0x04000000) != 0 /* XSAVE */ && (cpu_info[2] & 0x08000000) != 0 /* OSXSAVE */ && (_xgetbv(0) & 6) == 6 /* XSAVE enabled by kernel */; has_aesni_ = (cpu_info[2] & 0x02000000) != 0; |