xref: /kvm-unit-tests/x86/tsx-ctrl.c (revision 6163f75d09a0a96a5c3db82dd768b13f79629c00)
1*6163f75dSPaolo Bonzini /* TSX tests */
2*6163f75dSPaolo Bonzini 
3*6163f75dSPaolo Bonzini #include "libcflat.h"
4*6163f75dSPaolo Bonzini #include "processor.h"
5*6163f75dSPaolo Bonzini #include "msr.h"
6*6163f75dSPaolo Bonzini 
7*6163f75dSPaolo Bonzini static bool try_transaction(void)
8*6163f75dSPaolo Bonzini {
9*6163f75dSPaolo Bonzini     unsigned x;
10*6163f75dSPaolo Bonzini     int i;
11*6163f75dSPaolo Bonzini 
12*6163f75dSPaolo Bonzini     for (i = 0; i < 100; i++) {
13*6163f75dSPaolo Bonzini         x = 0;
14*6163f75dSPaolo Bonzini         /*
15*6163f75dSPaolo Bonzini          * The value before the transaction is important, so make the
16*6163f75dSPaolo Bonzini          * operand input/output.
17*6163f75dSPaolo Bonzini          */
18*6163f75dSPaolo Bonzini         asm volatile("xbegin 2f; movb $1, %0; xend; 2:" : "+m" (x) : : "eax");
19*6163f75dSPaolo Bonzini         if (x) {
20*6163f75dSPaolo Bonzini             return true;
21*6163f75dSPaolo Bonzini         }
22*6163f75dSPaolo Bonzini     }
23*6163f75dSPaolo Bonzini     return false;
24*6163f75dSPaolo Bonzini }
25*6163f75dSPaolo Bonzini 
26*6163f75dSPaolo Bonzini int main(int ac, char **av)
27*6163f75dSPaolo Bonzini {
28*6163f75dSPaolo Bonzini     if (!this_cpu_has(X86_FEATURE_RTM)) {
29*6163f75dSPaolo Bonzini         report_skip("TSX not available");
30*6163f75dSPaolo Bonzini 	return 0;
31*6163f75dSPaolo Bonzini     }
32*6163f75dSPaolo Bonzini     if (!this_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) {
33*6163f75dSPaolo Bonzini         report_skip("ARCH_CAPABILITIES not available");
34*6163f75dSPaolo Bonzini 	return 0;
35*6163f75dSPaolo Bonzini     }
36*6163f75dSPaolo Bonzini     if (!(rdmsr(MSR_IA32_ARCH_CAPABILITIES) & ARCH_CAP_TSX_CTRL_MSR)) {
37*6163f75dSPaolo Bonzini         report_skip("TSX_CTRL not available");
38*6163f75dSPaolo Bonzini 	return 0;
39*6163f75dSPaolo Bonzini     }
40*6163f75dSPaolo Bonzini 
41*6163f75dSPaolo Bonzini     report("TSX_CTRL should be 0", rdmsr(MSR_IA32_TSX_CTRL) == 0);
42*6163f75dSPaolo Bonzini     report("Transactions do not abort", try_transaction());
43*6163f75dSPaolo Bonzini 
44*6163f75dSPaolo Bonzini     wrmsr(MSR_IA32_TSX_CTRL, TSX_CTRL_CPUID_CLEAR);
45*6163f75dSPaolo Bonzini     report("TSX_CTRL hides RTM", !this_cpu_has(X86_FEATURE_RTM));
46*6163f75dSPaolo Bonzini     report("TSX_CTRL hides HLE", !this_cpu_has(X86_FEATURE_HLE));
47*6163f75dSPaolo Bonzini 
48*6163f75dSPaolo Bonzini     /* Microcode might hide HLE unconditionally */
49*6163f75dSPaolo Bonzini     wrmsr(MSR_IA32_TSX_CTRL, 0);
50*6163f75dSPaolo Bonzini     report("TSX_CTRL=0 unhides RTM", this_cpu_has(X86_FEATURE_RTM));
51*6163f75dSPaolo Bonzini 
52*6163f75dSPaolo Bonzini     wrmsr(MSR_IA32_TSX_CTRL, TSX_CTRL_RTM_DISABLE);
53*6163f75dSPaolo Bonzini     report("TSX_CTRL causes transactions to abort", !try_transaction());
54*6163f75dSPaolo Bonzini 
55*6163f75dSPaolo Bonzini     wrmsr(MSR_IA32_TSX_CTRL, 0);
56*6163f75dSPaolo Bonzini     report("TSX_CTRL=0 causes transactions to succeed", try_transaction());
57*6163f75dSPaolo Bonzini 
58*6163f75dSPaolo Bonzini     return report_summary();
59*6163f75dSPaolo Bonzini }
60*6163f75dSPaolo Bonzini 
61