@@ -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 ;
@@ -236,6 +239,7 @@ void __init cpu_select_mitigations(void)
236239 its_select_mitigation ();
237240 bhi_select_mitigation ();
238241 tsa_select_mitigation ();
242+ vmscape_select_mitigation ();
239243
240244 /*
241245 * After mitigations are selected, some may need to update their
@@ -267,6 +271,7 @@ void __init cpu_select_mitigations(void)
267271 bhi_update_mitigation ();
268272 /* srso_update_mitigation() depends on retbleed_update_mitigation(). */
269273 srso_update_mitigation ();
274+ vmscape_update_mitigation ();
270275
271276 spectre_v1_apply_mitigation ();
272277 spectre_v2_apply_mitigation ();
@@ -284,6 +289,7 @@ void __init cpu_select_mitigations(void)
284289 its_apply_mitigation ();
285290 bhi_apply_mitigation ();
286291 tsa_apply_mitigation ();
292+ vmscape_apply_mitigation ();
287293}
288294
289295/*
@@ -3138,6 +3144,77 @@ static void __init srso_apply_mitigation(void)
31383144 }
31393145}
31403146
3147+ #undef pr_fmt
3148+ #define pr_fmt (fmt ) "VMSCAPE: " fmt
3149+
3150+ enum vmscape_mitigations {
3151+ VMSCAPE_MITIGATION_NONE ,
3152+ VMSCAPE_MITIGATION_AUTO ,
3153+ VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ,
3154+ VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ,
3155+ };
3156+
3157+ static const char * const vmscape_strings [] = {
3158+ [VMSCAPE_MITIGATION_NONE ] = "Vulnerable" ,
3159+ /* [VMSCAPE_MITIGATION_AUTO] */
3160+ [VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ] = "Mitigation: IBPB before exit to userspace" ,
3161+ [VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ] = "Mitigation: IBPB on VMEXIT" ,
3162+ };
3163+
3164+ static enum vmscape_mitigations vmscape_mitigation __ro_after_init =
3165+ IS_ENABLED (CONFIG_MITIGATION_VMSCAPE ) ? VMSCAPE_MITIGATION_AUTO : VMSCAPE_MITIGATION_NONE ;
3166+
3167+ static int __init vmscape_parse_cmdline (char * str )
3168+ {
3169+ if (!str )
3170+ return - EINVAL ;
3171+
3172+ if (!strcmp (str , "off" )) {
3173+ vmscape_mitigation = VMSCAPE_MITIGATION_NONE ;
3174+ } else if (!strcmp (str , "ibpb" )) {
3175+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ;
3176+ } else if (!strcmp (str , "force" )) {
3177+ setup_force_cpu_bug (X86_BUG_VMSCAPE );
3178+ vmscape_mitigation = VMSCAPE_MITIGATION_AUTO ;
3179+ } else {
3180+ pr_err ("Ignoring unknown vmscape=%s option.\n" , str );
3181+ }
3182+
3183+ return 0 ;
3184+ }
3185+ early_param ("vmscape" , vmscape_parse_cmdline );
3186+
3187+ static void __init vmscape_select_mitigation (void )
3188+ {
3189+ if (cpu_mitigations_off () ||
3190+ !boot_cpu_has_bug (X86_BUG_VMSCAPE ) ||
3191+ !boot_cpu_has (X86_FEATURE_IBPB )) {
3192+ vmscape_mitigation = VMSCAPE_MITIGATION_NONE ;
3193+ return ;
3194+ }
3195+
3196+ if (vmscape_mitigation == VMSCAPE_MITIGATION_AUTO )
3197+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ;
3198+ }
3199+
3200+ static void __init vmscape_update_mitigation (void )
3201+ {
3202+ if (!boot_cpu_has_bug (X86_BUG_VMSCAPE ))
3203+ return ;
3204+
3205+ if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB ||
3206+ srso_mitigation == SRSO_MITIGATION_IBPB_ON_VMEXIT )
3207+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ;
3208+
3209+ pr_info ("%s\n" , vmscape_strings [vmscape_mitigation ]);
3210+ }
3211+
3212+ static void __init vmscape_apply_mitigation (void )
3213+ {
3214+ if (vmscape_mitigation == VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER )
3215+ setup_force_cpu_cap (X86_FEATURE_IBPB_EXIT_TO_USER );
3216+ }
3217+
31413218#undef pr_fmt
31423219#define pr_fmt (fmt ) fmt
31433220
@@ -3381,6 +3458,11 @@ static ssize_t tsa_show_state(char *buf)
33813458 return sysfs_emit (buf , "%s\n" , tsa_strings [tsa_mitigation ]);
33823459}
33833460
3461+ static ssize_t vmscape_show_state (char * buf )
3462+ {
3463+ return sysfs_emit (buf , "%s\n" , vmscape_strings [vmscape_mitigation ]);
3464+ }
3465+
33843466static ssize_t cpu_show_common (struct device * dev , struct device_attribute * attr ,
33853467 char * buf , unsigned int bug )
33863468{
@@ -3444,6 +3526,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
34443526 case X86_BUG_TSA :
34453527 return tsa_show_state (buf );
34463528
3529+ case X86_BUG_VMSCAPE :
3530+ return vmscape_show_state (buf );
3531+
34473532 default :
34483533 break ;
34493534 }
@@ -3530,6 +3615,11 @@ ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *bu
35303615{
35313616 return cpu_show_common (dev , attr , buf , X86_BUG_TSA );
35323617}
3618+
3619+ ssize_t cpu_show_vmscape (struct device * dev , struct device_attribute * attr , char * buf )
3620+ {
3621+ return cpu_show_common (dev , attr , buf , X86_BUG_VMSCAPE );
3622+ }
35333623#endif
35343624
35353625void __warn_thunk (void )
0 commit comments