@@ -49,6 +49,7 @@ static void __init l1d_flush_select_mitigation(void);
4949static void __init gds_select_mitigation (void );
5050static void __init srso_select_mitigation (void );
5151static void __init its_select_mitigation (void );
52+ static void __init tsa_select_mitigation (void );
5253
5354/* The base value of the SPEC_CTRL MSR without task-specific bits set */
5455u64 x86_spec_ctrl_base ;
@@ -184,6 +185,7 @@ void __init cpu_select_mitigations(void)
184185 srso_select_mitigation ();
185186 gds_select_mitigation ();
186187 its_select_mitigation ();
188+ tsa_select_mitigation ();
187189}
188190
189191/*
@@ -2039,6 +2041,94 @@ static void update_mds_branch_idle(void)
20392041#define TAA_MSG_SMT "TAA CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/tsx_async_abort.html for more details.\n"
20402042#define MMIO_MSG_SMT "MMIO Stale Data CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/processor_mmio_stale_data.html for more details.\n"
20412043
2044+ #undef pr_fmt
2045+ #define pr_fmt (fmt ) "Transient Scheduler Attacks: " fmt
2046+
2047+ enum tsa_mitigations {
2048+ TSA_MITIGATION_NONE ,
2049+ TSA_MITIGATION_UCODE_NEEDED ,
2050+ TSA_MITIGATION_USER_KERNEL ,
2051+ TSA_MITIGATION_VM ,
2052+ TSA_MITIGATION_FULL ,
2053+ };
2054+
2055+ static const char * const tsa_strings [] = {
2056+ [TSA_MITIGATION_NONE ] = "Vulnerable" ,
2057+ [TSA_MITIGATION_UCODE_NEEDED ] = "Vulnerable: Clear CPU buffers attempted, no microcode" ,
2058+ [TSA_MITIGATION_USER_KERNEL ] = "Mitigation: Clear CPU buffers: user/kernel boundary" ,
2059+ [TSA_MITIGATION_VM ] = "Mitigation: Clear CPU buffers: VM" ,
2060+ [TSA_MITIGATION_FULL ] = "Mitigation: Clear CPU buffers" ,
2061+ };
2062+
2063+ static enum tsa_mitigations tsa_mitigation __ro_after_init =
2064+ IS_ENABLED (CONFIG_MITIGATION_TSA ) ? TSA_MITIGATION_FULL : TSA_MITIGATION_NONE ;
2065+
2066+ static int __init tsa_parse_cmdline (char * str )
2067+ {
2068+ if (!str )
2069+ return - EINVAL ;
2070+
2071+ if (!strcmp (str , "off" ))
2072+ tsa_mitigation = TSA_MITIGATION_NONE ;
2073+ else if (!strcmp (str , "on" ))
2074+ tsa_mitigation = TSA_MITIGATION_FULL ;
2075+ else if (!strcmp (str , "user" ))
2076+ tsa_mitigation = TSA_MITIGATION_USER_KERNEL ;
2077+ else if (!strcmp (str , "vm" ))
2078+ tsa_mitigation = TSA_MITIGATION_VM ;
2079+ else
2080+ pr_err ("Ignoring unknown tsa=%s option.\n" , str );
2081+
2082+ return 0 ;
2083+ }
2084+ early_param ("tsa" , tsa_parse_cmdline );
2085+
2086+ static void __init tsa_select_mitigation (void )
2087+ {
2088+ if (tsa_mitigation == TSA_MITIGATION_NONE )
2089+ return ;
2090+
2091+ if (cpu_mitigations_off () || !boot_cpu_has_bug (X86_BUG_TSA )) {
2092+ tsa_mitigation = TSA_MITIGATION_NONE ;
2093+ return ;
2094+ }
2095+
2096+ if (!boot_cpu_has (X86_FEATURE_VERW_CLEAR ))
2097+ tsa_mitigation = TSA_MITIGATION_UCODE_NEEDED ;
2098+
2099+ switch (tsa_mitigation ) {
2100+ case TSA_MITIGATION_USER_KERNEL :
2101+ setup_force_cpu_cap (X86_FEATURE_CLEAR_CPU_BUF );
2102+ break ;
2103+
2104+ case TSA_MITIGATION_VM :
2105+ setup_force_cpu_cap (X86_FEATURE_CLEAR_CPU_BUF_VM );
2106+ break ;
2107+
2108+ case TSA_MITIGATION_UCODE_NEEDED :
2109+ if (!boot_cpu_has (X86_FEATURE_HYPERVISOR ))
2110+ goto out ;
2111+
2112+ pr_notice ("Forcing mitigation on in a VM\n" );
2113+
2114+ /*
2115+ * On the off-chance that microcode has been updated
2116+ * on the host, enable the mitigation in the guest just
2117+ * in case.
2118+ */
2119+ fallthrough ;
2120+ case TSA_MITIGATION_FULL :
2121+ setup_force_cpu_cap (X86_FEATURE_CLEAR_CPU_BUF );
2122+ setup_force_cpu_cap (X86_FEATURE_CLEAR_CPU_BUF_VM );
2123+ break ;
2124+ default :
2125+ break ;
2126+ }
2127+
2128+ out :
2129+ pr_info ("%s\n" , tsa_strings [tsa_mitigation ]);
2130+ }
2131+
20422132void cpu_bugs_smt_update (void )
20432133{
20442134 mutex_lock (& spec_ctrl_mutex );
@@ -2092,6 +2182,24 @@ void cpu_bugs_smt_update(void)
20922182 break ;
20932183 }
20942184
2185+ switch (tsa_mitigation ) {
2186+ case TSA_MITIGATION_USER_KERNEL :
2187+ case TSA_MITIGATION_VM :
2188+ case TSA_MITIGATION_FULL :
2189+ case TSA_MITIGATION_UCODE_NEEDED :
2190+ /*
2191+ * TSA-SQ can potentially lead to info leakage between
2192+ * SMT threads.
2193+ */
2194+ if (sched_smt_active ())
2195+ static_branch_enable (& cpu_buf_idle_clear );
2196+ else
2197+ static_branch_disable (& cpu_buf_idle_clear );
2198+ break ;
2199+ case TSA_MITIGATION_NONE :
2200+ break ;
2201+ }
2202+
20952203 mutex_unlock (& spec_ctrl_mutex );
20962204}
20972205
@@ -3026,6 +3134,11 @@ static ssize_t srso_show_state(char *buf)
30263134 boot_cpu_has (X86_FEATURE_IBPB_BRTYPE ) ? "" : ", no microcode" );
30273135}
30283136
3137+ static ssize_t tsa_show_state (char * buf )
3138+ {
3139+ return sysfs_emit (buf , "%s\n" , tsa_strings [tsa_mitigation ]);
3140+ }
3141+
30293142static ssize_t cpu_show_common (struct device * dev , struct device_attribute * attr ,
30303143 char * buf , unsigned int bug )
30313144{
@@ -3087,6 +3200,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
30873200 case X86_BUG_ITS :
30883201 return its_show_state (buf );
30893202
3203+ case X86_BUG_TSA :
3204+ return tsa_show_state (buf );
3205+
30903206 default :
30913207 break ;
30923208 }
@@ -3171,4 +3287,9 @@ ssize_t cpu_show_indirect_target_selection(struct device *dev, struct device_att
31713287{
31723288 return cpu_show_common (dev , attr , buf , X86_BUG_ITS );
31733289}
3290+
3291+ ssize_t cpu_show_tsa (struct device * dev , struct device_attribute * attr , char * buf )
3292+ {
3293+ return cpu_show_common (dev , attr , buf , X86_BUG_TSA );
3294+ }
31743295#endif
0 commit comments