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