]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Changes in shared code that don't affect open-vm-tools functionality.
authorVMware, Inc <>
Mon, 26 Jul 2010 18:21:37 +0000 (11:21 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Mon, 26 Jul 2010 18:21:37 +0000 (11:21 -0700)
Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/lib/include/vm_basic_asm_x86.h
open-vm-tools/lib/include/vm_basic_asm_x86_64.h
open-vm-tools/lib/include/x86cpuid.h

index 864429e91495b0bea5b3886f6d9f9ea6c38902e8..45f37f941d5d5ff3b451c97122333df88e7c7640 100644 (file)
@@ -114,6 +114,80 @@ FXRSTOR_AMD_ES0(const uint8 *load)
 }
 #endif /* __GNUC__ */
 
+/*
+ * XSAVE/XRSTOR
+ *     save/restore GSSE/SIMD/MMX fpu state
+ *
+ * The pointer passed in must be 64-byte aligned.
+ * See above comment for more information.
+ */
+#if defined(__GNUC__) && (defined(VMM) || defined(VMKERNEL) || defined(FROBOS))
+
+static INLINE void 
+XSAVE_ES1(uint8 *save, uint64 mask)
+{
+#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
+   __asm__ __volatile__ (
+        ".byte 0x0f, 0xae, 0x21 \n"
+        :
+        : "c" (save), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#else
+   __asm__ __volatile__ (
+        "xsave %0 \n"
+        : "=m" (*save)
+        : "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#endif
+}
+
+static INLINE void 
+XRSTOR_ES1(const uint8 *load, uint64 mask)
+{
+#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
+   __asm__ __volatile__ (
+        ".byte 0x0f, 0xae, 0x29 \n"
+        :
+        : "c" (load), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#else
+   __asm__ __volatile__ (
+        "xrstor %0 \n"
+        :
+        : "m" (*load), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#endif
+}
+
+static INLINE void 
+XRSTOR_AMD_ES0(const uint8 *load, uint64 mask)
+{
+   uint64 dummy = 0;
+      
+   __asm__ __volatile__ 
+       ("fnstsw  %%ax    \n"     // Grab x87 ES bit
+        "bt      $7,%%ax \n"     // Test ES bit
+        "jnc     1f      \n"     // Jump if ES=0
+        "fnclex          \n"     // ES=1. Clear it so fild doesn't trap
+        "1:              \n"
+        "ffree   %%st(7) \n"     // Clear tag bit - avoid poss. stack overflow
+        "fildl   %0      \n"     // Dummy Load from "safe address" changes all
+                                 // x87 exception pointers.
+        "mov %%ebx, %%eax \n"
+#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
+        ".byte 0x0f, 0xae, 0x29 \n"
+        :
+        : "m" (dummy),
+          "c" (load), "b" ((uint32)mask), "d" ((uint32)(mask >> 32))
+#else
+        "xrstor %1 \n"
+        :
+        : "m" (dummy), "m" (*load), "b" ((uint32)mask), "d" ((uint32)(mask >> 32))
+#endif
+        : "eax", "memory");
+}
+#endif /* __GNUC__ */
+
 /*
  *-----------------------------------------------------------------------------
  *
index d73d5515e95347c3dbb7c2c20885742c76bf0381..c42f3f2aa24b948ba995ef7c85f6d5214c65d6bf 100644 (file)
@@ -140,6 +140,117 @@ FXRSTOR_AMD_ES0(const uint8 *load)
 
 #endif /* __GNUC__ */
 
+/*
+ * XSAVE/XRSTOR
+ *     save/restore GSSE/SIMD/MMX fpu state
+ *
+ * The pointer passed in must be 64-byte aligned.
+ * See above comment for more information.
+ */
+#if defined(__GNUC__) && (defined(VMM) || defined(VMKERNEL) || defined(FROBOS))
+
+static INLINE void 
+XSAVE_ES1(uint8 *save, uint64 mask)
+{
+#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
+   __asm__ __volatile__ (
+        ".byte 0x48, 0x0f, 0xae, 0x21 \n"
+        :
+        : "c" (save), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#else
+   __asm__ __volatile__ (
+        "xsaveq %0 \n"
+        : "=m" (*save)
+        : "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#endif
+}
+
+static INLINE void 
+XSAVE_COMPAT_ES1(uint8 *save, uint64 mask)
+{
+#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
+   __asm__ __volatile__ (
+        ".byte 0x0f, 0xae, 0x21 \n"
+        :
+        : "c" (save), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#else
+   __asm__ __volatile__ (
+        "xsave %0 \n"
+        : "=m" (*save)
+        : "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#endif
+}
+
+static INLINE void 
+XRSTOR_ES1(const uint8 *load, uint64 mask)
+{
+#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
+   __asm__ __volatile__ (
+        ".byte 0x48, 0x0f, 0xae, 0x29 \n"
+        :
+        : "c" (load), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#else
+   __asm__ __volatile__ (
+        "xrstorq %0 \n"
+        :
+        : "m" (*load), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#endif
+}
+
+static INLINE void 
+XRSTOR_COMPAT_ES1(const uint8 *load, uint64 mask)
+{
+#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
+   __asm__ __volatile__ (
+        ".byte 0x0f, 0xae, 0x29 \n"
+        :
+        : "c" (load), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#else
+   __asm__ __volatile__ (
+        "xrstor %0 \n"
+        :
+        : "m" (*load), "a" ((uint32)mask), "d" ((uint32)(mask >> 32))
+        : "memory");
+#endif
+}
+
+static INLINE void 
+XRSTOR_AMD_ES0(const uint8 *load, uint64 mask)
+{
+   uint64 dummy = 0;
+      
+   __asm__ __volatile__ 
+       ("fnstsw  %%ax    \n"     // Grab x87 ES bit
+        "bt      $7,%%ax \n"     // Test ES bit
+        "jnc     1f      \n"     // Jump if ES=0
+        "fnclex          \n"     // ES=1. Clear it so fild doesn't trap
+        "1:              \n"
+        "ffree   %%st(7) \n"     // Clear tag bit - avoid poss. stack overflow
+        "fildl   %0      \n"     // Dummy Load from "safe address" changes all
+                                 // x87 exception pointers.
+        "mov %%ebx, %%eax \n"
+#if __GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ == 1
+        ".byte 0x48, 0x0f, 0xae, 0x29 \n"
+        :
+        : "m" (dummy),
+          "c" (load), "b" ((uint32)mask), "d" ((uint32)(mask >> 32))
+#else
+        "xrstorq %1 \n"
+        :
+        : "m" (dummy), "m" (*load), "b" ((uint32)mask), "d" ((uint32)(mask >> 32))
+#endif
+        : "eax", "memory");
+}
+
+#endif /* __GNUC__ */
+
 
 /*
  *-----------------------------------------------------------------------------
index e3d3c4d27e309c298ab4bc375cc10652009cff6b..c6e45138bcd798f9f0d131a6618975f090a41bd2 100644 (file)
@@ -127,6 +127,7 @@ CPUIDQuery;
    CPUIDLEVEL(FALSE, 6, 6)                      \
    CPUIDLEVEL(FALSE, A, 0xA)                    \
    CPUIDLEVEL(FALSE, B, 0xB)                    \
+   CPUIDLEVEL(FALSE, D, 0xD)                    \
    CPUIDLEVEL(FALSE, 86, 0x80000006)
 
 #define CPUID_ALL_LEVELS                        \
@@ -298,9 +299,9 @@ FLAGDEFA(  1, ECX, INTEL,  22,  1, MOVBE,               YES, TRUE,  MOVBE)     \
 FLAGDEFA(  1, ECX, COMMON, 23,  1, POPCNT,              YES, TRUE,  POPCNT)    \
 FLAGDEF(   1, ECX, INTEL,  24,  1, ULE,                 NO,  TRUE)             \
 FLAGDEFA(  1, ECX, INTEL,  25,  1, AES,                 YES, TRUE, AES)        \
-FLAGDEFA(  1, ECX, INTEL,  26,  1, XSAVE,               NO,  FALSE, XSAVE)     \
-FLAGDEF(   1, ECX, INTEL,  27,  1, OSXSAVE,             NO,  TRUE)             \
-FLAGDEFA(  1, ECX, INTEL,  28,  1, AVX,                 NO,  TRUE,  AVX)       \
+FLAGDEFA(  1, ECX, COMMON, 26,  1, XSAVE,               NO,  FALSE, XSAVE)     \
+FLAGDEF(   1, ECX, COMMON, 27,  1, OSXSAVE,             NO,  TRUE)             \
+FLAGDEFA(  1, ECX, COMMON, 28,  1, AVX,                 NO,  TRUE,  AVX)       \
 FLAGDEFA(  1, ECX, COMMON, 31,  1, HYPERVISOR,          ANY, FALSE, HYPERVISOR)\
 FLAGDEFA(  1, EDX, COMMON, 0,   1, FPU,                 YES, TRUE, FPU)        \
 FLAGDEFA(  1, EDX, COMMON, 1,   1, VME,                 YES, FALSE, VME)       \
@@ -392,6 +393,13 @@ FIELDDEF(  B, ECX, INTEL,   0,  8, LEVEL_NUMBER,        NA,  FALSE)            \
 FIELDDEF(  B, ECX, INTEL,   8,  8, LEVEL_TYPE,          NA,  FALSE)            \
 FIELDDEF(  B, EDX, INTEL,   0, 32, X2APIC_ID,           NA,  FALSE)
 
+/*    LEVEL, REG, VENDOR, POS, SIZE, NAME,       MON SUPP, CPL3, [FUNC] */
+#define CPUID_FIELD_DATA_LEVEL_D                                               \
+FIELDDEFA( D, EAX, COMMON,  0, 32, XCR0_MASTER_LOWER,   NA,  FALSE, XCR0_MASTER_LOWER) \
+FIELDDEF(  D, EBX, COMMON,  0, 32, XSAVE_ENABLED_SIZE,  NA,  FALSE)           \
+FIELDDEFA( D, ECX, COMMON,  0, 32, XSAVE_MAX_SIZE,      NA,  FALSE, XSAVE_MAX_SIZE) \
+FIELDDEFA( D, EDX, COMMON,  0, 32, XCR0_MASTER_UPPER,   NA,  FALSE, XCR0_MASTER_UPPER)
+
 /*    LEVEL, REG, VENDOR, POS, SIZE, NAME,       MON SUPP, CPL3, [FUNC] */
 #define CPUID_FIELD_DATA_LEVEL_400                                             \
 FIELDDEF(400, EAX, COMMON,  0, 32, NUM_HYP_LEVELS,      NA,  FALSE)            \
@@ -517,6 +525,7 @@ FIELDDEF( 8A, EDX, AMD,    11, 21, SVMEDX_RSVD1,        NO,  FALSE)
    CPUID_FIELD_DATA_LEVEL_6                                           \
    CPUID_FIELD_DATA_LEVEL_A                                           \
    CPUID_FIELD_DATA_LEVEL_B                                           \
+   CPUID_FIELD_DATA_LEVEL_D                                           \
    CPUID_FIELD_DATA_LEVEL_400                                         \
    CPUID_FIELD_DATA_LEVEL_410                                         \
    CPUID_FIELD_DATA_LEVEL_80                                          \