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