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("clflush (%s)", ud == expected, expected ? "ABSENT" : "present"); 40 41 expected = !this_cpu_has(X86_FEATURE_XMM); /* SSE */ 42 ud = 0; 43 asm volatile("sfence"); 44 report("sfence (%s)", ud == expected, expected ? "ABSENT" : "present"); 45 46 expected = !this_cpu_has(X86_FEATURE_XMM2); /* SSE2 */ 47 ud = 0; 48 asm volatile("lfence"); 49 report("lfence (%s)", ud == expected, expected ? "ABSENT" : "present"); 50 51 ud = 0; 52 asm volatile("mfence"); 53 report("mfence (%s)", ud == expected, 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("clflushopt (%s)", ud == expected, expected ? "ABSENT" : "present"); 63 64 expected = !this_cpu_has(X86_FEATURE_CLWB); /* CLWB */ 65 ud = 0; 66 /* clwb (%rbx): */ 67 asm volatile(".byte 0x66, 0x0f, 0xae, 0x33" : : "b" (&target)); 68 report("clwb (%s)", ud == expected, expected ? "ABSENT" : "present"); 69 70 ud = 0; 71 /* clwb requires a memory operand, the following is NOT a valid 72 * CLWB instruction (modrm == 0xF0). 73 */ 74 asm volatile(".byte 0x66, 0x0f, 0xae, 0xf0"); 75 report("invalid clwb", ud); 76 77 expected = !this_cpu_has(X86_FEATURE_PCOMMIT); /* PCOMMIT */ 78 ud = 0; 79 /* pcommit: */ 80 asm volatile(".byte 0x66, 0x0f, 0xae, 0xf8"); 81 report("pcommit (%s)", ud == expected, expected ? "ABSENT" : "present"); 82 83 return report_summary(); 84 } 85