blob: 3b197ca6de81c24b7e7bde85927ba6dd67e22ec9 [file] [log] [blame]
/* 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();
}