diff options
Diffstat (limited to 'kvm/test/x86/xsave.c')
-rw-r--r-- | kvm/test/x86/xsave.c | 262 |
1 files changed, 0 insertions, 262 deletions
diff --git a/kvm/test/x86/xsave.c b/kvm/test/x86/xsave.c deleted file mode 100644 index a22b44c7f..000000000 --- a/kvm/test/x86/xsave.c +++ /dev/null @@ -1,262 +0,0 @@ -#include "libcflat.h" -#include "idt.h" - -#ifdef __x86_64__ -#define uint64_t unsigned long -#else -#define uint64_t unsigned long long -#endif - -static inline void __cpuid(unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - /* ecx is often an input as well as an output. */ - asm volatile("cpuid" - : "=a" (*eax), - "=b" (*ebx), - "=c" (*ecx), - "=d" (*edx) - : "0" (*eax), "2" (*ecx)); -} - -/* - * Generic CPUID function - * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx - * resulting in stale register contents being returned. - */ -void cpuid(unsigned int op, - unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - *eax = op; - *ecx = 0; - __cpuid(eax, ebx, ecx, edx); -} - -/* Some CPUID calls want 'count' to be placed in ecx */ -void cpuid_count(unsigned int op, int count, - unsigned int *eax, unsigned int *ebx, - unsigned int *ecx, unsigned int *edx) -{ - *eax = op; - *ecx = count; - __cpuid(eax, ebx, ecx, edx); -} - -int xgetbv_checking(u32 index, u64 *result) -{ - u32 eax, edx; - - asm volatile(ASM_TRY("1f") - ".byte 0x0f,0x01,0xd0\n\t" /* xgetbv */ - "1:" - : "=a" (eax), "=d" (edx) - : "c" (index)); - *result = eax + ((u64)edx << 32); - return exception_vector(); -} - -int xsetbv_checking(u32 index, u64 value) -{ - u32 eax = value; - u32 edx = value >> 32; - - asm volatile(ASM_TRY("1f") - ".byte 0x0f,0x01,0xd1\n\t" /* xsetbv */ - "1:" - : : "a" (eax), "d" (edx), "c" (index)); - return exception_vector(); -} - -unsigned long read_cr4(void) -{ - unsigned long val; - asm volatile("mov %%cr4,%0" : "=r" (val)); - return val; -} - -int write_cr4_checking(unsigned long val) -{ - asm volatile(ASM_TRY("1f") - "mov %0,%%cr4\n\t" - "1:": : "r" (val)); - return exception_vector(); -} - -#define CPUID_1_ECX_XSAVE (1 << 26) -#define CPUID_1_ECX_OSXSAVE (1 << 27) -int check_cpuid_1_ecx(unsigned int bit) -{ - unsigned int eax, ebx, ecx, edx; - cpuid(1, &eax, &ebx, &ecx, &edx); - if (ecx & bit) - return 1; - return 0; -} - -uint64_t get_supported_xcr0(void) -{ - unsigned int eax, ebx, ecx, edx; - cpuid_count(0xd, 0, &eax, &ebx, &ecx, &edx); - printf("eax %x, ebx %x, ecx %x, edx %x\n", - eax, ebx, ecx, edx); - return eax + ((u64)edx << 32); -} - -#define X86_CR4_OSXSAVE 0x00040000 -#define XCR_XFEATURE_ENABLED_MASK 0x00000000 -#define XCR_XFEATURE_ILLEGAL_MASK 0x00000010 - -#define XSTATE_FP 0x1 -#define XSTATE_SSE 0x2 -#define XSTATE_YMM 0x4 - -static int total_tests, fail_tests; - -void pass_if(int condition) -{ - total_tests ++; - if (condition) - printf("Pass!\n"); - else { - printf("Fail!\n"); - fail_tests ++; - } -} - -void test_xsave(void) -{ - unsigned long cr4; - uint64_t supported_xcr0; - uint64_t test_bits; - u64 xcr0; - int r; - - printf("Legal instruction testing:\n"); - supported_xcr0 = get_supported_xcr0(); - printf("Supported XCR0 bits: 0x%x\n", supported_xcr0); - - printf("Check minimal XSAVE required bits: "); - test_bits = XSTATE_FP | XSTATE_SSE; - pass_if((supported_xcr0 & test_bits) == test_bits); - - printf("Set CR4 OSXSAVE: "); - cr4 = read_cr4(); - r = write_cr4_checking(cr4 | X86_CR4_OSXSAVE); - pass_if(r == 0); - - printf("Check CPUID.1.ECX.OSXSAVE - expect 1: "); - pass_if(check_cpuid_1_ecx(CPUID_1_ECX_OSXSAVE)); - - printf(" Legal tests\n"); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP): "); - test_bits = XSTATE_FP; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == 0); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, " - "XSTATE_FP | XSTATE_SSE): "); - test_bits = XSTATE_FP | XSTATE_SSE; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == 0); - printf(" xgetbv(XCR_XFEATURE_ENABLED_MASK): "); - r = xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0); - pass_if(r == 0); - printf(" Illegal tests\n"); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, 0) - expect #GP: "); - test_bits = 0; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == GP_VECTOR); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_SSE) " - "- expect #GP: "); - test_bits = XSTATE_SSE; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == GP_VECTOR); - if (supported_xcr0 & XSTATE_YMM) { - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, " - "XSTATE_YMM) - expect #GP: "); - test_bits = XSTATE_YMM; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == GP_VECTOR); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, " - "XSTATE_FP | XSTATE_YMM) - expect #GP: "); - test_bits = XSTATE_FP | XSTATE_YMM; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == GP_VECTOR); - } - printf(" xsetbv(XCR_XFEATURE_ILLEGAL_MASK, XSTATE_FP) " - "- expect #GP: "); - test_bits = XSTATE_SSE; - r = xsetbv_checking(XCR_XFEATURE_ILLEGAL_MASK, test_bits); - pass_if(r == GP_VECTOR); - printf(" xgetbv(XCR_XFEATURE_ILLEGAL_MASK, XSTATE_FP) " - "- expect #GP: "); - test_bits = XSTATE_SSE; - r = xsetbv_checking(XCR_XFEATURE_ILLEGAL_MASK, test_bits); - pass_if(r == GP_VECTOR); - - printf("Unset CR4 OSXSAVE: "); - cr4 &= ~X86_CR4_OSXSAVE; - r = write_cr4_checking(cr4); - pass_if(r == 0); - printf("Check CPUID.1.ECX.OSXSAVE - expect 0: "); - pass_if(check_cpuid_1_ecx(CPUID_1_ECX_OSXSAVE) == 0); - printf(" Illegal tests:\n"); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP) - expect #UD: "); - test_bits = XSTATE_FP; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == UD_VECTOR); - printf(" xsetbv(XCR_XFEATURE_ENABLED_MASK, " - "XSTATE_FP | XSTATE_SSE) - expect #UD: "); - test_bits = XSTATE_FP | XSTATE_SSE; - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, test_bits); - pass_if(r == UD_VECTOR); - printf(" Illegal tests:\n"); - printf(" xgetbv(XCR_XFEATURE_ENABLED_MASK) - expect #UD: "); - r = xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0); - pass_if(r == UD_VECTOR); -} - -void test_no_xsave(void) -{ - unsigned long cr4; - u64 xcr0; - int r; - - printf("Check CPUID.1.ECX.OSXSAVE - expect 0: "); - pass_if(check_cpuid_1_ecx(CPUID_1_ECX_OSXSAVE) == 0); - - printf("Illegal instruction testing:\n"); - - printf("Set OSXSAVE in CR4 - expect #GP: "); - cr4 = read_cr4(); - r = write_cr4_checking(cr4 | X86_CR4_OSXSAVE); - pass_if(r == GP_VECTOR); - - printf("Execute xgetbv - expect #UD: "); - r = xgetbv_checking(XCR_XFEATURE_ENABLED_MASK, &xcr0); - pass_if(r == UD_VECTOR); - - printf("Execute xsetbv - expect #UD: "); - r = xsetbv_checking(XCR_XFEATURE_ENABLED_MASK, 0x3); - pass_if(r == UD_VECTOR); -} - -int main(void) -{ - setup_idt(); - if (check_cpuid_1_ecx(CPUID_1_ECX_XSAVE)) { - printf("CPU has XSAVE feature\n"); - test_xsave(); - } else { - printf("CPU don't has XSAVE feature\n"); - test_no_xsave(); - } - printf("Total test: %d\n", total_tests); - if (fail_tests == 0) - printf("ALL PASS!\n"); - else { - printf("Fail %d tests.\n", fail_tests); - return 1; - } - return 0; -} |