@@ -50,6 +50,7 @@ static void __init gds_select_mitigation(void);
5050static void __init srso_select_mitigation (void );
5151static void __init its_select_mitigation (void );
5252static void __init tsa_select_mitigation (void );
53+ static void __init vmscape_select_mitigation (void );
5354
5455/* The base value of the SPEC_CTRL MSR without task-specific bits set */
5556u64 x86_spec_ctrl_base ;
@@ -193,6 +194,7 @@ void __init cpu_select_mitigations(void)
193194 gds_select_mitigation ();
194195 its_select_mitigation ();
195196 tsa_select_mitigation ();
197+ vmscape_select_mitigation ();
196198}
197199
198200/*
@@ -2898,6 +2900,68 @@ static void __init srso_select_mitigation(void)
28982900 x86_pred_cmd = PRED_CMD_SBPB ;
28992901}
29002902
2903+ #undef pr_fmt
2904+ #define pr_fmt (fmt ) "VMSCAPE: " fmt
2905+
2906+ enum vmscape_mitigations {
2907+ VMSCAPE_MITIGATION_NONE ,
2908+ VMSCAPE_MITIGATION_AUTO ,
2909+ VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ,
2910+ VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ,
2911+ };
2912+
2913+ static const char * const vmscape_strings [] = {
2914+ [VMSCAPE_MITIGATION_NONE ] = "Vulnerable" ,
2915+ /* [VMSCAPE_MITIGATION_AUTO] */
2916+ [VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ] = "Mitigation: IBPB before exit to userspace" ,
2917+ [VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ] = "Mitigation: IBPB on VMEXIT" ,
2918+ };
2919+
2920+ static enum vmscape_mitigations vmscape_mitigation __ro_after_init =
2921+ IS_ENABLED (CONFIG_MITIGATION_VMSCAPE ) ? VMSCAPE_MITIGATION_AUTO : VMSCAPE_MITIGATION_NONE ;
2922+
2923+ static int __init vmscape_parse_cmdline (char * str )
2924+ {
2925+ if (!str )
2926+ return - EINVAL ;
2927+
2928+ if (!strcmp (str , "off" )) {
2929+ vmscape_mitigation = VMSCAPE_MITIGATION_NONE ;
2930+ } else if (!strcmp (str , "ibpb" )) {
2931+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ;
2932+ } else if (!strcmp (str , "force" )) {
2933+ setup_force_cpu_bug (X86_BUG_VMSCAPE );
2934+ vmscape_mitigation = VMSCAPE_MITIGATION_AUTO ;
2935+ } else {
2936+ pr_err ("Ignoring unknown vmscape=%s option.\n" , str );
2937+ }
2938+
2939+ return 0 ;
2940+ }
2941+ early_param ("vmscape" , vmscape_parse_cmdline );
2942+
2943+ static void __init vmscape_select_mitigation (void )
2944+ {
2945+ if (cpu_mitigations_off () ||
2946+ !boot_cpu_has_bug (X86_BUG_VMSCAPE ) ||
2947+ !boot_cpu_has (X86_FEATURE_IBPB )) {
2948+ vmscape_mitigation = VMSCAPE_MITIGATION_NONE ;
2949+ return ;
2950+ }
2951+
2952+ if (vmscape_mitigation == VMSCAPE_MITIGATION_AUTO )
2953+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ;
2954+
2955+ if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB ||
2956+ srso_mitigation == SRSO_MITIGATION_IBPB_ON_VMEXIT )
2957+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ;
2958+
2959+ if (vmscape_mitigation == VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER )
2960+ setup_force_cpu_cap (X86_FEATURE_IBPB_EXIT_TO_USER );
2961+
2962+ pr_info ("%s\n" , vmscape_strings [vmscape_mitigation ]);
2963+ }
2964+
29012965#undef pr_fmt
29022966#define pr_fmt (fmt ) fmt
29032967
@@ -3146,6 +3210,11 @@ static ssize_t tsa_show_state(char *buf)
31463210 return sysfs_emit (buf , "%s\n" , tsa_strings [tsa_mitigation ]);
31473211}
31483212
3213+ static ssize_t vmscape_show_state (char * buf )
3214+ {
3215+ return sysfs_emit (buf , "%s\n" , vmscape_strings [vmscape_mitigation ]);
3216+ }
3217+
31493218static ssize_t cpu_show_common (struct device * dev , struct device_attribute * attr ,
31503219 char * buf , unsigned int bug )
31513220{
@@ -3210,6 +3279,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
32103279 case X86_BUG_TSA :
32113280 return tsa_show_state (buf );
32123281
3282+ case X86_BUG_VMSCAPE :
3283+ return vmscape_show_state (buf );
3284+
32133285 default :
32143286 break ;
32153287 }
@@ -3299,4 +3371,9 @@ ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *bu
32993371{
33003372 return cpu_show_common (dev , attr , buf , X86_BUG_TSA );
33013373}
3374+
3375+ ssize_t cpu_show_vmscape (struct device * dev , struct device_attribute * attr , char * buf )
3376+ {
3377+ return cpu_show_common (dev , attr , buf , X86_BUG_VMSCAPE );
3378+ }
33023379#endif
0 commit comments