From: VMware, Inc <> Date: Mon, 26 Jul 2010 18:21:37 +0000 (-0700) Subject: Changes in shared code that don't affect open-vm-tools functionality. X-Git-Tag: 2010.07.25-280253~89 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=51f36f77ff0aae9d2bd92c1911f0b7210e7b2c9c;p=thirdparty%2Fopen-vm-tools.git Changes in shared code that don't affect open-vm-tools functionality. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/include/vm_basic_asm_x86.h b/open-vm-tools/lib/include/vm_basic_asm_x86.h index 864429e91..45f37f941 100644 --- a/open-vm-tools/lib/include/vm_basic_asm_x86.h +++ b/open-vm-tools/lib/include/vm_basic_asm_x86.h @@ -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__ */ + /* *----------------------------------------------------------------------------- * diff --git a/open-vm-tools/lib/include/vm_basic_asm_x86_64.h b/open-vm-tools/lib/include/vm_basic_asm_x86_64.h index d73d5515e..c42f3f2aa 100644 --- a/open-vm-tools/lib/include/vm_basic_asm_x86_64.h +++ b/open-vm-tools/lib/include/vm_basic_asm_x86_64.h @@ -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__ */ + /* *----------------------------------------------------------------------------- diff --git a/open-vm-tools/lib/include/x86cpuid.h b/open-vm-tools/lib/include/x86cpuid.h index e3d3c4d27..c6e45138b 100644 --- a/open-vm-tools/lib/include/x86cpuid.h +++ b/open-vm-tools/lib/include/x86cpuid.h @@ -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 \