Index: sys/amd64/amd64/machdep.c =================================================================== --- sys/amd64/amd64/machdep.c +++ sys/amd64/amd64/machdep.c @@ -1779,6 +1779,7 @@ TUNABLE_INT_FETCH("machdep.syscall_ret_l1d_flush", &syscall_ret_l1d_flush_mode); TUNABLE_INT_FETCH("hw.mds_disable", &hw_mds_disable); + TUNABLE_INT_FETCH("hw.tsx_disable", &hw_tsx_disable); /* XXX Should this be in x86? */ finishidentcpu(); /* Final stage of CPU initialization */ initializecpu(); /* Initialize CPU registers */ Index: sys/dev/cpuctl/cpuctl.c =================================================================== --- sys/dev/cpuctl/cpuctl.c +++ sys/dev/cpuctl/cpuctl.c @@ -546,6 +546,7 @@ pmap_allow_2m_x_ept_recalculate(); #endif hw_mds_recalculate(); + hw_tsx_recalculate(); printcpuinfo(); return (0); } Index: sys/x86/include/x86_var.h =================================================================== --- sys/x86/include/x86_var.h +++ sys/x86/include/x86_var.h @@ -93,6 +93,7 @@ extern int hw_ibrs_active; extern int hw_mds_disable; extern int hw_ssb_active; +extern int hw_tsx_disable; struct pcb; struct thread; @@ -136,6 +137,7 @@ void hw_ibrs_recalculate(void); void hw_mds_recalculate(void); void hw_ssb_recalculate(bool all_cpus); +void hw_tsx_recalculate(void); void nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame); void nmi_call_kdb_smp(u_int type, struct trapframe *frame); void nmi_handle_intr(u_int type, struct trapframe *frame); Index: sys/x86/x86/cpu_machdep.c =================================================================== --- sys/x86/x86/cpu_machdep.c +++ sys/x86/x86/cpu_machdep.c @@ -1135,6 +1135,66 @@ "Microarchitectural Data Sampling Mitigation " "(0 - off, 1 - on VERW, 2 - on SW, 3 - on AUTO"); +int hw_tsx_disable; +void +hw_tsx_recalculate(void) +{ + uint32_t regs[4]; + + /* Check CPUID.07h.EBX.HLE and RTM for the presence of TSX */ + /* XXX should we used the cached cpu_stdext_feature value? */ + do_cpuid(0x07, regs); + if ((regs[2] & CPUID_STDEXT_HLE) == 0 || + (regs[2] & CPUID_STDEXT_RTM) == 0) { + /* TSX is not present */ + return; + } + + if ((cpu_ia32_arch_caps & IA32_ARCH_CAP_TAA_NO) && + (hw_tsx_disable == 1)) { + hw_tsx_disable = 0; + } else if (cpu_ia32_arch_caps & IA32_ARCH_CAP_MDS_NO) { + if (cpu_ia32_arch_caps & IA32_ARCH_CAP_TSX_CTRL) + hw_tsx_disable = 1; + else { + hw_mds_disable = 1; + hw_mds_recalculate(); + return; + } + } + +} + +static void +hw_tsx_recalculate_boot(void * arg __unused) +{ + + hw_tsx_recalculate(); +} +SYSINIT(tsx_recalc, SI_SUB_SMP, SI_ORDER_ANY, hw_tsx_recalculate_boot, NULL); + +static int +sysctl_tsx_disable_handler(SYSCTL_HANDLER_ARGS) +{ + int error, val; + + val = hw_tsx_disable; + error = sysctl_handle_int(oidp, &val, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + if (val < 0 || val > 3) + return (EINVAL); + hw_tsx_disable = val; + hw_tsx_recalculate(); + return (0); +} + +SYSCTL_PROC(_hw, OID_AUTO, tsx_disable, CTLTYPE_INT | + CTLFLAG_RWTUN | CTLFLAG_NOFETCH | CTLFLAG_MPSAFE, NULL, 0, + sysctl_tsx_disable_handler, "I", + "TSX Asynchronous Abort Mitigation " + "(0 - off, 1 - disable TSX, 2 - MDS/VERW, 3 - on AUTO"); + /* * Enable and restore kernel text write permissions. * Callers must ensure that disable_wp()/restore_wp() are executed