1 /* 2 * Test for x86 cache and memory instructions 3 * 4 * Copyright (c) 2015 Red Hat Inc 5 * 6 * Authors: 7 * Eduardo Habkost <ehabkost@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2. 10 */ 11 12 #include "libcflat.h" 13 #include "desc.h" 14 #include "processor.h" 15 16 static long target; 17 static volatile int ud; 18 static volatile int isize; 19 20 static void handle_ud(struct ex_regs *regs) 21 { 22 ud = 1; 23 regs->rip += isize; 24 } 25 26 int main(int ac, char **av) 27 { 28 handle_exception(UD_VECTOR, handle_ud); 29 30 /* 3-byte instructions: */ 31 isize = 3; 32 33 if (this_cpu_has(X86_FEATURE_CLFLUSH)) { /* CLFLUSH */ 34 ud = 0; 35 asm volatile("clflush (%0)" : : "b" (&target)); 36 report(!ud, "clflush"); 37 } else { 38 report_skip("clflush"); 39 } 40 41 if (this_cpu_has(X86_FEATURE_XMM)) { /* SSE */ 42 ud = 0; 43 asm volatile("sfence"); 44 report(!ud, "sfence"); 45 } else { 46 report_skip("sfence"); 47 } 48 49 if (this_cpu_has(X86_FEATURE_XMM2)) { /* SSE2 */ 50 ud = 0; 51 asm volatile("lfence"); 52 report(!ud, "lfence"); 53 ud = 0; 54 asm volatile("mfence"); 55 report(!ud, "mfence"); 56 } else { 57 report_skip("lfence"); 58 report_skip("mfence"); 59 } 60 61 /* 4-byte instructions: */ 62 isize = 4; 63 64 if (this_cpu_has(X86_FEATURE_CLFLUSHOPT)) { /* CLFLUSHOPT */ 65 ud = 0; 66 /* clflushopt (%rbx): */ 67 asm volatile(".byte 0x66, 0x0f, 0xae, 0x3b" : : "b" (&target)); 68 report(!ud, "clflushopt"); 69 } else { 70 report_skip("clflushopt"); 71 } 72 73 if (this_cpu_has(X86_FEATURE_CLWB)) { /* CLWB */ 74 ud = 0; 75 /* clwb (%rbx): */ 76 asm volatile(".byte 0x66, 0x0f, 0xae, 0x33" : : "b" (&target)); 77 report(!ud, "clwb"); 78 } else { 79 report_skip("clwb"); 80 } 81 82 if (this_cpu_has(X86_FEATURE_PCOMMIT)) { /* PCOMMIT */ 83 ud = 0; 84 /* pcommit: */ 85 asm volatile(".byte 0x66, 0x0f, 0xae, 0xf8"); 86 report(!ud, "pcommit"); 87 } else { 88 report_skip("pcommit"); 89 } 90 91 return report_summary(); 92 } 93