@@ -96,6 +96,9 @@ static void __init its_update_mitigation(void);
9696static void __init its_apply_mitigation (void );
9797static void __init tsa_select_mitigation (void );
9898static void __init tsa_apply_mitigation (void );
99+ static void __init vmscape_select_mitigation (void );
100+ static void __init vmscape_update_mitigation (void );
101+ static void __init vmscape_apply_mitigation (void );
99102
100103/* The base value of the SPEC_CTRL MSR without task-specific bits set */
101104u64 x86_spec_ctrl_base ;
@@ -235,6 +238,7 @@ void __init cpu_select_mitigations(void)
235238 its_select_mitigation ();
236239 bhi_select_mitigation ();
237240 tsa_select_mitigation ();
241+ vmscape_select_mitigation ();
238242
239243 /*
240244 * After mitigations are selected, some may need to update their
@@ -266,6 +270,7 @@ void __init cpu_select_mitigations(void)
266270 bhi_update_mitigation ();
267271 /* srso_update_mitigation() depends on retbleed_update_mitigation(). */
268272 srso_update_mitigation ();
273+ vmscape_update_mitigation ();
269274
270275 spectre_v1_apply_mitigation ();
271276 spectre_v2_apply_mitigation ();
@@ -283,6 +288,7 @@ void __init cpu_select_mitigations(void)
283288 its_apply_mitigation ();
284289 bhi_apply_mitigation ();
285290 tsa_apply_mitigation ();
291+ vmscape_apply_mitigation ();
286292}
287293
288294/*
@@ -3145,6 +3151,77 @@ static void __init srso_apply_mitigation(void)
31453151 }
31463152}
31473153
3154+ #undef pr_fmt
3155+ #define pr_fmt (fmt ) "VMSCAPE: " fmt
3156+
3157+ enum vmscape_mitigations {
3158+ VMSCAPE_MITIGATION_NONE ,
3159+ VMSCAPE_MITIGATION_AUTO ,
3160+ VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ,
3161+ VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ,
3162+ };
3163+
3164+ static const char * const vmscape_strings [] = {
3165+ [VMSCAPE_MITIGATION_NONE ] = "Vulnerable" ,
3166+ /* [VMSCAPE_MITIGATION_AUTO] */
3167+ [VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ] = "Mitigation: IBPB before exit to userspace" ,
3168+ [VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ] = "Mitigation: IBPB on VMEXIT" ,
3169+ };
3170+
3171+ static enum vmscape_mitigations vmscape_mitigation __ro_after_init =
3172+ IS_ENABLED (CONFIG_MITIGATION_VMSCAPE ) ? VMSCAPE_MITIGATION_AUTO : VMSCAPE_MITIGATION_NONE ;
3173+
3174+ static int __init vmscape_parse_cmdline (char * str )
3175+ {
3176+ if (!str )
3177+ return - EINVAL ;
3178+
3179+ if (!strcmp (str , "off" )) {
3180+ vmscape_mitigation = VMSCAPE_MITIGATION_NONE ;
3181+ } else if (!strcmp (str , "ibpb" )) {
3182+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ;
3183+ } else if (!strcmp (str , "force" )) {
3184+ setup_force_cpu_bug (X86_BUG_VMSCAPE );
3185+ vmscape_mitigation = VMSCAPE_MITIGATION_AUTO ;
3186+ } else {
3187+ pr_err ("Ignoring unknown vmscape=%s option.\n" , str );
3188+ }
3189+
3190+ return 0 ;
3191+ }
3192+ early_param ("vmscape" , vmscape_parse_cmdline );
3193+
3194+ static void __init vmscape_select_mitigation (void )
3195+ {
3196+ if (cpu_mitigations_off () ||
3197+ !boot_cpu_has_bug (X86_BUG_VMSCAPE ) ||
3198+ !boot_cpu_has (X86_FEATURE_IBPB )) {
3199+ vmscape_mitigation = VMSCAPE_MITIGATION_NONE ;
3200+ return ;
3201+ }
3202+
3203+ if (vmscape_mitigation == VMSCAPE_MITIGATION_AUTO )
3204+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ;
3205+ }
3206+
3207+ static void __init vmscape_update_mitigation (void )
3208+ {
3209+ if (!boot_cpu_has_bug (X86_BUG_VMSCAPE ))
3210+ return ;
3211+
3212+ if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB ||
3213+ srso_mitigation == SRSO_MITIGATION_IBPB_ON_VMEXIT )
3214+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ;
3215+
3216+ pr_info ("%s\n" , vmscape_strings [vmscape_mitigation ]);
3217+ }
3218+
3219+ static void __init vmscape_apply_mitigation (void )
3220+ {
3221+ if (vmscape_mitigation == VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER )
3222+ setup_force_cpu_cap (X86_FEATURE_IBPB_EXIT_TO_USER );
3223+ }
3224+
31483225#undef pr_fmt
31493226#define pr_fmt (fmt ) fmt
31503227
@@ -3396,6 +3473,11 @@ static ssize_t tsa_show_state(char *buf)
33963473 return sysfs_emit (buf , "%s\n" , tsa_strings [tsa_mitigation ]);
33973474}
33983475
3476+ static ssize_t vmscape_show_state (char * buf )
3477+ {
3478+ return sysfs_emit (buf , "%s\n" , vmscape_strings [vmscape_mitigation ]);
3479+ }
3480+
33993481static ssize_t cpu_show_common (struct device * dev , struct device_attribute * attr ,
34003482 char * buf , unsigned int bug )
34013483{
@@ -3462,6 +3544,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
34623544 case X86_BUG_TSA :
34633545 return tsa_show_state (buf );
34643546
3547+ case X86_BUG_VMSCAPE :
3548+ return vmscape_show_state (buf );
3549+
34653550 default :
34663551 break ;
34673552 }
@@ -3553,6 +3638,11 @@ ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *bu
35533638{
35543639 return cpu_show_common (dev , attr , buf , X86_BUG_TSA );
35553640}
3641+
3642+ ssize_t cpu_show_vmscape (struct device * dev , struct device_attribute * attr , char * buf )
3643+ {
3644+ return cpu_show_common (dev , attr , buf , X86_BUG_VMSCAPE );
3645+ }
35563646#endif
35573647
35583648void __warn_thunk (void )
0 commit comments