@@ -566,6 +566,8 @@ void arch_smt_update(void)
566
566
case SPECTRE_V2_USER_STRICT :
567
567
update_stibp_strict ();
568
568
break ;
569
+ case SPECTRE_V2_USER_PRCTL :
570
+ break ;
569
571
}
570
572
571
573
mutex_unlock (& spec_ctrl_mutex );
@@ -752,12 +754,50 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
752
754
return 0 ;
753
755
}
754
756
757
+ static int ib_prctl_set (struct task_struct * task , unsigned long ctrl )
758
+ {
759
+ switch (ctrl ) {
760
+ case PR_SPEC_ENABLE :
761
+ if (spectre_v2_user == SPECTRE_V2_USER_NONE )
762
+ return 0 ;
763
+ /*
764
+ * Indirect branch speculation is always disabled in strict
765
+ * mode.
766
+ */
767
+ if (spectre_v2_user == SPECTRE_V2_USER_STRICT )
768
+ return - EPERM ;
769
+ task_clear_spec_ib_disable (task );
770
+ task_update_spec_tif (task );
771
+ break ;
772
+ case PR_SPEC_DISABLE :
773
+ case PR_SPEC_FORCE_DISABLE :
774
+ /*
775
+ * Indirect branch speculation is always allowed when
776
+ * mitigation is force disabled.
777
+ */
778
+ if (spectre_v2_user == SPECTRE_V2_USER_NONE )
779
+ return - EPERM ;
780
+ if (spectre_v2_user == SPECTRE_V2_USER_STRICT )
781
+ return 0 ;
782
+ task_set_spec_ib_disable (task );
783
+ if (ctrl == PR_SPEC_FORCE_DISABLE )
784
+ task_set_spec_ib_force_disable (task );
785
+ task_update_spec_tif (task );
786
+ break ;
787
+ default :
788
+ return - ERANGE ;
789
+ }
790
+ return 0 ;
791
+ }
792
+
755
793
int arch_prctl_spec_ctrl_set (struct task_struct * task , unsigned long which ,
756
794
unsigned long ctrl )
757
795
{
758
796
switch (which ) {
759
797
case PR_SPEC_STORE_BYPASS :
760
798
return ssb_prctl_set (task , ctrl );
799
+ case PR_SPEC_INDIRECT_BRANCH :
800
+ return ib_prctl_set (task , ctrl );
761
801
default :
762
802
return - ENODEV ;
763
803
}
@@ -790,11 +830,34 @@ static int ssb_prctl_get(struct task_struct *task)
790
830
}
791
831
}
792
832
833
+ static int ib_prctl_get (struct task_struct * task )
834
+ {
835
+ if (!boot_cpu_has_bug (X86_BUG_SPECTRE_V2 ))
836
+ return PR_SPEC_NOT_AFFECTED ;
837
+
838
+ switch (spectre_v2_user ) {
839
+ case SPECTRE_V2_USER_NONE :
840
+ return PR_SPEC_ENABLE ;
841
+ case SPECTRE_V2_USER_PRCTL :
842
+ if (task_spec_ib_force_disable (task ))
843
+ return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE ;
844
+ if (task_spec_ib_disable (task ))
845
+ return PR_SPEC_PRCTL | PR_SPEC_DISABLE ;
846
+ return PR_SPEC_PRCTL | PR_SPEC_ENABLE ;
847
+ case SPECTRE_V2_USER_STRICT :
848
+ return PR_SPEC_DISABLE ;
849
+ default :
850
+ return PR_SPEC_NOT_AFFECTED ;
851
+ }
852
+ }
853
+
793
854
int arch_prctl_spec_ctrl_get (struct task_struct * task , unsigned long which )
794
855
{
795
856
switch (which ) {
796
857
case PR_SPEC_STORE_BYPASS :
797
858
return ssb_prctl_get (task );
859
+ case PR_SPEC_INDIRECT_BRANCH :
860
+ return ib_prctl_get (task );
798
861
default :
799
862
return - ENODEV ;
800
863
}
@@ -974,6 +1037,8 @@ static char *stibp_state(void)
974
1037
return ", STIBP: disabled" ;
975
1038
case SPECTRE_V2_USER_STRICT :
976
1039
return ", STIBP: forced" ;
1040
+ case SPECTRE_V2_USER_PRCTL :
1041
+ return "" ;
977
1042
}
978
1043
return "" ;
979
1044
}
@@ -986,6 +1051,8 @@ static char *ibpb_state(void)
986
1051
return ", IBPB: disabled" ;
987
1052
case SPECTRE_V2_USER_STRICT :
988
1053
return ", IBPB: always-on" ;
1054
+ case SPECTRE_V2_USER_PRCTL :
1055
+ return "" ;
989
1056
}
990
1057
}
991
1058
return "" ;
0 commit comments