Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(633)

Unified Diff: base/cpu.cc

Issue 79283002: crypto: disable NSS AES-NI support when AVX is disabled by OS. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use base::Environment Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/cpu.cc
diff --git a/base/cpu.cc b/base/cpu.cc
index 78064e2815f4bed5da737174289374748707e6e5..7cc0e40b2052c8fbae8f8bce1661eca8d42498b8 100644
--- a/base/cpu.cc
+++ b/base/cpu.cc
@@ -8,11 +8,13 @@
#include <algorithm>
+#include "base/basictypes.h"
#include "build/build_config.h"
#if defined(ARCH_CPU_X86_FAMILY)
#if defined(_MSC_VER)
#include <intrin.h>
+#include <immintrin.h> // For _xgetbv()
#endif
#endif
@@ -33,11 +35,15 @@ CPU::CPU()
has_ssse3_(false),
has_sse41_(false),
has_sse42_(false),
+ has_avx_(false),
+ has_avx_hardware_(false),
has_non_stop_time_stamp_counter_(false),
cpu_vendor_("unknown") {
Initialize();
}
+namespace {
+
#if defined(ARCH_CPU_X86_FAMILY)
#ifndef _MSC_VER
@@ -53,16 +59,6 @@ void __cpuid(int cpu_info[4], int info_type) {
);
}
-void __cpuidex(int cpu_info[4], int info_type, int info_index) {
- __asm__ volatile (
- "mov %%ebx, %%edi\n"
- "cpuid\n"
- "xchg %%edi, %%ebx\n"
- : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
- : "a"(info_type), "c"(info_index)
- );
-}
-
#else
void __cpuid(int cpu_info[4], int info_type) {
@@ -73,18 +69,22 @@ void __cpuid(int cpu_info[4], int info_type) {
);
}
-void __cpuidex(int cpu_info[4], int info_type, int info_index) {
- __asm__ volatile (
- "cpuid \n\t"
- : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
- : "a"(info_type), "c"(info_index)
- );
-}
-
#endif
-#endif // _MSC_VER
+
+// _xgetbv returns the value of an Intel Extended Control Register (XCR).
+// Currently only XCR0 is defined by Intel so |xcr| should always be zero.
+uint64 _xgetbv(uint32 xcr) {
+ uint32 eax, edx;
+
+ __asm__ volatile ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (xcr));
+ return (static_cast<uint64>(edx) << 32) | eax;
+}
+
+#endif // !_MSC_VER
#endif // ARCH_CPU_X86_FAMILY
+} // anonymous namespace
+
void CPU::Initialize() {
#if defined(ARCH_CPU_X86_FAMILY)
int cpu_info[4] = {-1};
@@ -113,14 +113,24 @@ void CPU::Initialize() {
type_ = (cpu_info[0] >> 12) & 0x3;
ext_model_ = (cpu_info[0] >> 16) & 0xf;
ext_family_ = (cpu_info[0] >> 20) & 0xff;
- has_mmx_ = (cpu_info[3] & 0x00800000) != 0;
- has_sse_ = (cpu_info[3] & 0x02000000) != 0;
- has_sse2_ = (cpu_info[3] & 0x04000000) != 0;
- has_sse3_ = (cpu_info[2] & 0x00000001) != 0;
+ has_mmx_ = (cpu_info[3] & 0x00800000) != 0;
+ has_sse_ = (cpu_info[3] & 0x02000000) != 0;
+ has_sse2_ = (cpu_info[3] & 0x04000000) != 0;
+ has_sse3_ = (cpu_info[2] & 0x00000001) != 0;
has_ssse3_ = (cpu_info[2] & 0x00000200) != 0;
has_sse41_ = (cpu_info[2] & 0x00080000) != 0;
has_sse42_ = (cpu_info[2] & 0x00100000) != 0;
- has_avx_ = (cpu_info[2] & 0x10000000) != 0;
+ has_avx_hardware_ =
+ (cpu_info[2] & 0x10000000) != 0;
+ /* AVX instructions will generate an illegal instruction exception unless
+ * a) they are supported by the CPU,
+ * 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 */
wtc 2013/11/21 21:03:44 Use C++ comment //.
agl 2013/11/22 16:22:35 Done.
+ has_avx_ =
+ has_avx_hardware_ &&
+ (cpu_info[2] & 0x08000000) == 0x08000000 /* OSXSAVE */ &&
wtc 2013/11/21 21:03:44 Nit: since 0x08000000 has only one bit, you can ju
agl 2013/11/22 16:22:35 Done.
+ (_xgetbv(0) & 6) == 6 /* XSAVE enabled by kernel */;
wtc 2013/11/21 21:03:44 Nit: indent by four spaces
agl 2013/11/22 16:22:35 Done.
}
// Get the brand string of the cpu.

Powered by Google App Engine
This is Rietveld 408576698