1 #include "libcflat.h" 2 #include "desc.h" 3 #include "processor.h" 4 5 #ifdef __x86_64__ 6 #define uint64_t unsigned long 7 #else 8 #define uint64_t unsigned long long 9 #endif 10 11 static uint64_t get_supported_xcr0(void) 12 { 13 struct cpuid r; 14 r = cpuid_indexed(0xd, 0); 15 printf("eax %x, ebx %x, ecx %x, edx %x\n", 16 r.a, r.b, r.c, r.d); 17 return r.a + ((u64)r.d << 32); 18 } 19 20 #define XCR_XFEATURE_ENABLED_MASK 0x00000000 21 #define XCR_XFEATURE_ILLEGAL_MASK 0x00000010 22 23 #define XSTATE_FP 0x1 24 #define XSTATE_SSE 0x2 25 #define XSTATE_YMM 0x4 26 27 static void test_xsave(void) 28 { 29 unsigned long cr4; 30 uint64_t supported_xcr0; 31 uint64_t test_bits; 32 u64 xcr0; 33 34 printf("Legal instruction testing:\n"); 35 36 supported_xcr0 = get_supported_xcr0(); 37 printf("Supported XCR0 bits: %#lx\n", supported_xcr0); 38 39 test_bits = XSTATE_FP | XSTATE_SSE; 40 report((supported_xcr0 & test_bits) == test_bits, 41 "Check minimal XSAVE required bits"); 42 43 cr4 = read_cr4(); 44 report(write_cr4_safe(cr4 | X86_CR4_OSXSAVE) == 0, "Set CR4 OSXSAVE"); 45 report(this_cpu_has(X86_FEATURE_OSXSAVE), 46 "Check CPUID.1.ECX.OSXSAVE - expect 1"); 47 48 printf("\tLegal tests\n"); 49 test_bits = XSTATE_FP; 50 report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, test_bits) == 0, 51 "\t\txsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP)"); 52 53 test_bits = XSTATE_FP | XSTATE_SSE; 54 report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, test_bits) == 0, 55 "\t\txsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP | XSTATE_SSE)"); 56 report(xgetbv_safe(XCR_XFEATURE_ENABLED_MASK, &xcr0) == 0, 57 " xgetbv(XCR_XFEATURE_ENABLED_MASK)"); 58 59 printf("\tIllegal tests\n"); 60 test_bits = 0; 61 report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, test_bits) == GP_VECTOR, 62 "\t\txsetbv(XCR_XFEATURE_ENABLED_MASK, 0) - expect #GP"); 63 64 test_bits = XSTATE_SSE; 65 report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, test_bits) == GP_VECTOR, 66 "\t\txsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_SSE) - expect #GP"); 67 68 if (supported_xcr0 & XSTATE_YMM) { 69 test_bits = XSTATE_YMM; 70 report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, test_bits) == GP_VECTOR, 71 "\t\txsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_YMM) - expect #GP"); 72 73 test_bits = XSTATE_FP | XSTATE_YMM; 74 report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, test_bits) == GP_VECTOR, 75 "\t\txsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP | XSTATE_YMM) - expect #GP"); 76 } 77 78 test_bits = XSTATE_SSE; 79 report(xsetbv_safe(XCR_XFEATURE_ILLEGAL_MASK, test_bits) == GP_VECTOR, 80 "\t\txsetbv(XCR_XFEATURE_ILLEGAL_MASK, XSTATE_FP) - expect #GP"); 81 82 test_bits = XSTATE_SSE; 83 report(xsetbv_safe(XCR_XFEATURE_ILLEGAL_MASK, test_bits) == GP_VECTOR, 84 "\t\txgetbv(XCR_XFEATURE_ILLEGAL_MASK, XSTATE_FP) - expect #GP"); 85 86 cr4 &= ~X86_CR4_OSXSAVE; 87 report(write_cr4_safe(cr4) == 0, "Unset CR4 OSXSAVE"); 88 report(this_cpu_has(X86_FEATURE_OSXSAVE) == 0, 89 "Check CPUID.1.ECX.OSXSAVE - expect 0"); 90 91 printf("\tIllegal tests:\n"); 92 test_bits = XSTATE_FP; 93 report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, test_bits) == UD_VECTOR, 94 "\t\txsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP) - expect #UD"); 95 96 test_bits = XSTATE_FP | XSTATE_SSE; 97 report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, test_bits) == UD_VECTOR, 98 "\t\txsetbv(XCR_XFEATURE_ENABLED_MASK, XSTATE_FP | XSTATE_SSE) - expect #UD"); 99 100 printf("\tIllegal tests:\n"); 101 report(xgetbv_safe(XCR_XFEATURE_ENABLED_MASK, &xcr0) == UD_VECTOR, 102 "\txgetbv(XCR_XFEATURE_ENABLED_MASK) - expect #UD"); 103 } 104 105 static void test_no_xsave(void) 106 { 107 unsigned long cr4; 108 u64 xcr0; 109 110 report(this_cpu_has(X86_FEATURE_OSXSAVE) == 0, 111 "Check CPUID.1.ECX.OSXSAVE - expect 0"); 112 113 printf("Illegal instruction testing:\n"); 114 115 cr4 = read_cr4(); 116 report(write_cr4_safe(cr4 | X86_CR4_OSXSAVE) == GP_VECTOR, 117 "Set OSXSAVE in CR4 - expect #GP"); 118 119 report(xgetbv_safe(XCR_XFEATURE_ENABLED_MASK, &xcr0) == UD_VECTOR, 120 "Execute xgetbv - expect #UD"); 121 122 report(xsetbv_safe(XCR_XFEATURE_ENABLED_MASK, 0x3) == UD_VECTOR, 123 "Execute xsetbv - expect #UD"); 124 } 125 126 int main(void) 127 { 128 if (this_cpu_has(X86_FEATURE_XSAVE)) { 129 printf("CPU has XSAVE feature\n"); 130 test_xsave(); 131 } else { 132 printf("CPU don't has XSAVE feature\n"); 133 test_no_xsave(); 134 } 135 return report_summary(); 136 } 137