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 int expected; 29 30 setup_idt(); 31 handle_exception(UD_VECTOR, handle_ud); 32 33 /* 3-byte instructions: */ 34 isize = 3; 35 36 expected = !this_cpu_has(X86_FEATURE_CLFLUSH); /* CLFLUSH */ 37 ud = 0; 38 asm volatile("clflush (%0)" : : "b" (&target)); 39 report(ud == expected, "clflush (%s)", expected ? "ABSENT" : "present"); 40 41 expected = !this_cpu_has(X86_FEATURE_XMM); /* SSE */ 42 ud = 0; 43 asm volatile("sfence"); 44 report(ud == expected, "sfence (%s)", expected ? "ABSENT" : "present"); 45 46 expected = !this_cpu_has(X86_FEATURE_XMM2); /* SSE2 */ 47 ud = 0; 48 asm volatile("lfence"); 49 report(ud == expected, "lfence (%s)", expected ? "ABSENT" : "present"); 50 51 ud = 0; 52 asm volatile("mfence"); 53 report(ud == expected, "mfence (%s)", expected ? "ABSENT" : "present"); 54 55 /* 4-byte instructions: */ 56 isize = 4; 57 58 expected = !this_cpu_has(X86_FEATURE_CLFLUSHOPT); /* CLFLUSHOPT */ 59 ud = 0; 60 /* clflushopt (%rbx): */ 61 asm volatile(".byte 0x66, 0x0f, 0xae, 0x3b" : : "b" (&target)); 62 report(ud == expected, "clflushopt (%s)", 63 expected ? "ABSENT" : "present"); 64 65 expected = !this_cpu_has(X86_FEATURE_CLWB); /* CLWB */ 66 ud = 0; 67 /* clwb (%rbx): */ 68 asm volatile(".byte 0x66, 0x0f, 0xae, 0x33" : : "b" (&target)); 69 report(ud == expected, "clwb (%s)", expected ? "ABSENT" : "present"); 70 71 ud = 0; 72 /* clwb requires a memory operand, the following is NOT a valid 73 * CLWB instruction (modrm == 0xF0). 74 */ 75 asm volatile(".byte 0x66, 0x0f, 0xae, 0xf0"); 76 report(ud, "invalid clwb"); 77 78 expected = !this_cpu_has(X86_FEATURE_PCOMMIT); /* PCOMMIT */ 79 ud = 0; 80 /* pcommit: */ 81 asm volatile(".byte 0x66, 0x0f, 0xae, 0xf8"); 82 report(ud == expected, "pcommit (%s)", expected ? "ABSENT" : "present"); 83 84 return report_summary(); 85 } 86