Check if xsave is enabled by OS before calling xgetbv in XmmYmmStateSupport (dotnet...
authorCesar Blum Silveira <cesarbs@gmail.com>
Sat, 14 Jan 2017 00:09:46 +0000 (16:09 -0800)
committerJan Vorlicek <janvorli@microsoft.com>
Sat, 14 Jan 2017 00:09:46 +0000 (01:09 +0100)
* Check if xsave is enabled by OS before calling xgetbv in XmmYmmStateSupport. Fix dotnet/coreclr#8903

* Add ebx to clobbered registers.

Commit migrated from https://github.com/dotnet/coreclr/commit/590ff450b982e73782286ff3da80cd5665457de9

src/coreclr/src/pal/src/arch/amd64/processor.cpp

index ac3d448..298d685 100644 (file)
@@ -54,10 +54,18 @@ Return value:
 extern "C" unsigned int XmmYmmStateSupport()
 {
     unsigned int eax;
-    __asm("  xgetbv\n" \
-        : "=a"(eax) /*output in eax*/\
-        : "c"(0) /*inputs - 0 in ecx*/\
-        : "eax", "edx" /* registers that are clobbered*/
+    __asm("  mov $1, %%eax\n" \
+          "  cpuid\n" \
+          "  xor %%eax, %%eax\n" \
+          "  and $0x18000000, %%ecx\n" /* check for xsave feature set and that it is enabled by the OS */ \
+          "  cmp $0x18000000, %%ecx\n" \
+          "  jne end\n" \
+          "  xor %%ecx, %%ecx\n" \
+          "  xgetbv\n" \
+          "end:\n" \
+        : "=a"(eax) /* output in eax */ \
+        : /* no inputs */ \
+        : "eax", "ebx", "ecx", "edx" /* registers that are clobbered */
       );
     // Check OS has enabled both XMM and YMM state support
     return ((eax & 0x06) == 0x06) ? 1 : 0;