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