| /* TSX tests */ | |
| #include "libcflat.h" | |
| #include "processor.h" | |
| #include "msr.h" | |
| static bool try_transaction(void) | |
| { | |
| unsigned x; | |
| int i; | |
| for (i = 0; i < 100; i++) { | |
| x = 0; | |
| /* | |
| * The value before the transaction is important, so make the | |
| * operand input/output. | |
| */ | |
| asm volatile("xbegin 2f; movb $1, %0; xend; 2:" : "+m" (x) : : "eax"); | |
| if (x) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| int main(int ac, char **av) | |
| { | |
| if (!this_cpu_has(X86_FEATURE_RTM)) { | |
| report_skip("TSX not available"); | |
| return report_summary(); | |
| } | |
| if (!this_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) { | |
| report_skip("ARCH_CAPABILITIES not available"); | |
| return report_summary(); | |
| } | |
| if (!(rdmsr(MSR_IA32_ARCH_CAPABILITIES) & ARCH_CAP_TSX_CTRL_MSR)) { | |
| report_skip("TSX_CTRL not available"); | |
| return report_summary(); | |
| } | |
| report(rdmsr(MSR_IA32_TSX_CTRL) == 0, "TSX_CTRL should be 0"); | |
| report(try_transaction(), "Transactions do not abort"); | |
| wrmsr(MSR_IA32_TSX_CTRL, TSX_CTRL_CPUID_CLEAR); | |
| report(!this_cpu_has(X86_FEATURE_RTM), "TSX_CTRL hides RTM"); | |
| report(!this_cpu_has(X86_FEATURE_HLE), "TSX_CTRL hides HLE"); | |
| /* Microcode might hide HLE unconditionally */ | |
| wrmsr(MSR_IA32_TSX_CTRL, 0); | |
| report(this_cpu_has(X86_FEATURE_RTM), "TSX_CTRL=0 unhides RTM"); | |
| wrmsr(MSR_IA32_TSX_CTRL, TSX_CTRL_RTM_DISABLE); | |
| report(!try_transaction(), "TSX_CTRL causes transactions to abort"); | |
| wrmsr(MSR_IA32_TSX_CTRL, 0); | |
| report(try_transaction(), "TSX_CTRL=0 causes transactions to succeed"); | |
| return report_summary(); | |
| } | |