1 #include <xen/init.h>
2 #include <xen/param.h>
3 #include <asm/msr.h>
4
5 /*
6 * Valid values:
7 * 1 => Explicit tsx=1
8 * 0 => Explicit tsx=0
9 * -1 => Default, implicit tsx=1, may change to 0 to mitigate TAA
10 * -3 => Implicit tsx=1 (feed-through from spec-ctrl=0)
11 *
12 * This is arranged such that the bottom bit encodes whether TSX is actually
13 * disabled, while identifying various explicit (>=0) and implicit (<0)
14 * conditions.
15 */
16 int8_t __read_mostly opt_tsx = -1;
17 int8_t __read_mostly cpu_has_tsx_ctrl = -1;
18
parse_tsx(const char * s)19 static int __init parse_tsx(const char *s)
20 {
21 int rc = 0, val = parse_bool(s, NULL);
22
23 if ( val >= 0 )
24 opt_tsx = val;
25 else
26 rc = -EINVAL;
27
28 return rc;
29 }
30 custom_param("tsx", parse_tsx);
31
tsx_init(void)32 void tsx_init(void)
33 {
34 /*
35 * This function is first called between microcode being loaded, and CPUID
36 * being scanned generally. Calculate from raw data whether MSR_TSX_CTRL
37 * is available.
38 */
39 if ( unlikely(cpu_has_tsx_ctrl < 0) )
40 {
41 uint64_t caps = 0;
42
43 if ( boot_cpu_data.cpuid_level >= 7 &&
44 (cpuid_count_edx(7, 0) & cpufeat_mask(X86_FEATURE_ARCH_CAPS)) )
45 rdmsrl(MSR_ARCH_CAPABILITIES, caps);
46
47 cpu_has_tsx_ctrl = !!(caps & ARCH_CAPS_TSX_CTRL);
48 }
49
50 if ( cpu_has_tsx_ctrl )
51 {
52 uint64_t val;
53
54 rdmsrl(MSR_TSX_CTRL, val);
55
56 val &= ~(TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR);
57 /* Check bottom bit only. Higher bits are various sentinals. */
58 if ( !(opt_tsx & 1) )
59 val |= TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR;
60
61 wrmsrl(MSR_TSX_CTRL, val);
62 }
63 else if ( opt_tsx >= 0 )
64 printk_once(XENLOG_WARNING
65 "MSR_TSX_CTRL not available - Ignoring tsx= setting\n");
66 }
67
68 /*
69 * Local variables:
70 * mode: C
71 * c-file-style: "BSD"
72 * c-basic-offset: 4
73 * tab-width: 4
74 * indent-tabs-mode: nil
75 * End:
76 */
77