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