@@ -51,6 +51,7 @@ static void __init srso_select_mitigation(void);
5151static void __init gds_select_mitigation (void );
5252static void __init its_select_mitigation (void );
5353static void __init tsa_select_mitigation (void );
54+ static void __init vmscape_select_mitigation (void );
5455
5556/* The base value of the SPEC_CTRL MSR without task-specific bits set */
5657u64 x86_spec_ctrl_base ;
@@ -194,6 +195,7 @@ void __init cpu_select_mitigations(void)
194195 gds_select_mitigation ();
195196 its_select_mitigation ();
196197 tsa_select_mitigation ();
198+ vmscape_select_mitigation ();
197199}
198200
199201/*
@@ -2958,6 +2960,68 @@ static void __init srso_select_mitigation(void)
29582960 pr_info ("%s\n" , srso_strings [srso_mitigation ]);
29592961}
29602962
2963+ #undef pr_fmt
2964+ #define pr_fmt (fmt ) "VMSCAPE: " fmt
2965+
2966+ enum vmscape_mitigations {
2967+ VMSCAPE_MITIGATION_NONE ,
2968+ VMSCAPE_MITIGATION_AUTO ,
2969+ VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ,
2970+ VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ,
2971+ };
2972+
2973+ static const char * const vmscape_strings [] = {
2974+ [VMSCAPE_MITIGATION_NONE ] = "Vulnerable" ,
2975+ /* [VMSCAPE_MITIGATION_AUTO] */
2976+ [VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ] = "Mitigation: IBPB before exit to userspace" ,
2977+ [VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ] = "Mitigation: IBPB on VMEXIT" ,
2978+ };
2979+
2980+ static enum vmscape_mitigations vmscape_mitigation __ro_after_init =
2981+ IS_ENABLED (CONFIG_MITIGATION_VMSCAPE ) ? VMSCAPE_MITIGATION_AUTO : VMSCAPE_MITIGATION_NONE ;
2982+
2983+ static int __init vmscape_parse_cmdline (char * str )
2984+ {
2985+ if (!str )
2986+ return - EINVAL ;
2987+
2988+ if (!strcmp (str , "off" )) {
2989+ vmscape_mitigation = VMSCAPE_MITIGATION_NONE ;
2990+ } else if (!strcmp (str , "ibpb" )) {
2991+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ;
2992+ } else if (!strcmp (str , "force" )) {
2993+ setup_force_cpu_bug (X86_BUG_VMSCAPE );
2994+ vmscape_mitigation = VMSCAPE_MITIGATION_AUTO ;
2995+ } else {
2996+ pr_err ("Ignoring unknown vmscape=%s option.\n" , str );
2997+ }
2998+
2999+ return 0 ;
3000+ }
3001+ early_param ("vmscape" , vmscape_parse_cmdline );
3002+
3003+ static void __init vmscape_select_mitigation (void )
3004+ {
3005+ if (cpu_mitigations_off () ||
3006+ !boot_cpu_has_bug (X86_BUG_VMSCAPE ) ||
3007+ !boot_cpu_has (X86_FEATURE_IBPB )) {
3008+ vmscape_mitigation = VMSCAPE_MITIGATION_NONE ;
3009+ return ;
3010+ }
3011+
3012+ if (vmscape_mitigation == VMSCAPE_MITIGATION_AUTO )
3013+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER ;
3014+
3015+ if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB ||
3016+ srso_mitigation == SRSO_MITIGATION_IBPB_ON_VMEXIT )
3017+ vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_ON_VMEXIT ;
3018+
3019+ if (vmscape_mitigation == VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER )
3020+ setup_force_cpu_cap (X86_FEATURE_IBPB_EXIT_TO_USER );
3021+
3022+ pr_info ("%s\n" , vmscape_strings [vmscape_mitigation ]);
3023+ }
3024+
29613025#undef pr_fmt
29623026#define pr_fmt (fmt ) fmt
29633027
@@ -3204,6 +3268,11 @@ static ssize_t tsa_show_state(char *buf)
32043268 return sysfs_emit (buf , "%s\n" , tsa_strings [tsa_mitigation ]);
32053269}
32063270
3271+ static ssize_t vmscape_show_state (char * buf )
3272+ {
3273+ return sysfs_emit (buf , "%s\n" , vmscape_strings [vmscape_mitigation ]);
3274+ }
3275+
32073276static ssize_t cpu_show_common (struct device * dev , struct device_attribute * attr ,
32083277 char * buf , unsigned int bug )
32093278{
@@ -3268,6 +3337,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
32683337 case X86_BUG_TSA :
32693338 return tsa_show_state (buf );
32703339
3340+ case X86_BUG_VMSCAPE :
3341+ return vmscape_show_state (buf );
3342+
32713343 default :
32723344 break ;
32733345 }
@@ -3357,6 +3429,11 @@ ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *bu
33573429{
33583430 return cpu_show_common (dev , attr , buf , X86_BUG_TSA );
33593431}
3432+
3433+ ssize_t cpu_show_vmscape (struct device * dev , struct device_attribute * attr , char * buf )
3434+ {
3435+ return cpu_show_common (dev , attr , buf , X86_BUG_VMSCAPE );
3436+ }
33603437#endif
33613438
33623439void __warn_thunk (void )
0 commit comments