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 handle_exception(UD_VECTOR, handle_ud); 31 32 /* 3-byte instructions: */ 33 isize = 3; 34 35 expected = !this_cpu_has(X86_FEATURE_CLFLUSH); /* CLFLUSH */ 36 ud = 0; 37 asm volatile("clflush (%0)" : : "b" (&target)); 38 report(ud == expected, "clflush (%s)", expected ? "ABSENT" : "present"); 39 40 expected = !this_cpu_has(X86_FEATURE_XMM); /* SSE */ 41 ud = 0; 42 asm volatile("sfence"); 43 report(ud == expected, "sfence (%s)", expected ? "ABSENT" : "present"); 44 45 expected = !this_cpu_has(X86_FEATURE_XMM2); /* SSE2 */ 46 ud = 0; 47 asm volatile("lfence"); 48 report(ud == expected, "lfence (%s)", expected ? "ABSENT" : "present"); 49 50 ud = 0; 51 asm volatile("mfence"); 52 report(ud == expected, "mfence (%s)", expected ? "ABSENT" : "present"); 53 54 /* 4-byte instructions: */ 55 isize = 4; 56 57 expected = !this_cpu_has(X86_FEATURE_CLFLUSHOPT); /* CLFLUSHOPT */ 58 ud = 0; 59 /* clflushopt (%rbx): */ 60 asm volatile(".byte 0x66, 0x0f, 0xae, 0x3b" : : "b" (&target)); 61 report(ud == expected, "clflushopt (%s)", 62 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(ud == expected, "clwb (%s)", 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(ud, "invalid clwb"); 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(ud == expected, "pcommit (%s)", expected ? "ABSENT" : "present"); 82 83 return report_summary(); 84 } 85