.. | .. |
---|
159 | 159 | __sve_free(task); |
---|
160 | 160 | } |
---|
161 | 161 | |
---|
| 162 | +static void *sve_free_atomic(struct task_struct *task) |
---|
| 163 | +{ |
---|
| 164 | + void *sve_state = task->thread.sve_state; |
---|
| 165 | + |
---|
| 166 | + WARN_ON(test_tsk_thread_flag(task, TIF_SVE)); |
---|
| 167 | + |
---|
| 168 | + task->thread.sve_state = NULL; |
---|
| 169 | + return sve_state; |
---|
| 170 | +} |
---|
| 171 | + |
---|
162 | 172 | /* |
---|
163 | 173 | * TIF_SVE controls whether a task can use SVE without trapping while |
---|
164 | 174 | * in userspace, and also the way a task's FPSIMD/SVE state is stored |
---|
.. | .. |
---|
549 | 559 | * non-SVE thread. |
---|
550 | 560 | */ |
---|
551 | 561 | if (task == current) { |
---|
| 562 | + preempt_disable(); |
---|
552 | 563 | local_bh_disable(); |
---|
553 | 564 | |
---|
554 | 565 | fpsimd_save(); |
---|
.. | .. |
---|
559 | 570 | if (test_and_clear_tsk_thread_flag(task, TIF_SVE)) |
---|
560 | 571 | sve_to_fpsimd(task); |
---|
561 | 572 | |
---|
562 | | - if (task == current) |
---|
| 573 | + if (task == current) { |
---|
563 | 574 | local_bh_enable(); |
---|
| 575 | + preempt_enable(); |
---|
| 576 | + } |
---|
564 | 577 | |
---|
565 | 578 | /* |
---|
566 | 579 | * Force reallocation of task SVE state to the correct size |
---|
.. | .. |
---|
815 | 828 | |
---|
816 | 829 | sve_alloc(current); |
---|
817 | 830 | |
---|
| 831 | + preempt_disable(); |
---|
818 | 832 | local_bh_disable(); |
---|
819 | 833 | |
---|
820 | 834 | fpsimd_save(); |
---|
.. | .. |
---|
828 | 842 | WARN_ON(1); /* SVE access shouldn't have trapped */ |
---|
829 | 843 | |
---|
830 | 844 | local_bh_enable(); |
---|
| 845 | + preempt_enable(); |
---|
831 | 846 | } |
---|
832 | 847 | |
---|
833 | 848 | /* |
---|
.. | .. |
---|
894 | 909 | void fpsimd_flush_thread(void) |
---|
895 | 910 | { |
---|
896 | 911 | int vl, supported_vl; |
---|
| 912 | + void *mem = NULL; |
---|
897 | 913 | |
---|
898 | 914 | if (!system_supports_fpsimd()) |
---|
899 | 915 | return; |
---|
900 | 916 | |
---|
| 917 | + preempt_disable(); |
---|
901 | 918 | local_bh_disable(); |
---|
902 | 919 | |
---|
903 | 920 | memset(¤t->thread.uw.fpsimd_state, 0, |
---|
.. | .. |
---|
906 | 923 | |
---|
907 | 924 | if (system_supports_sve()) { |
---|
908 | 925 | clear_thread_flag(TIF_SVE); |
---|
909 | | - sve_free(current); |
---|
| 926 | + mem = sve_free_atomic(current); |
---|
910 | 927 | |
---|
911 | 928 | /* |
---|
912 | 929 | * Reset the task vector length as required. |
---|
.. | .. |
---|
942 | 959 | set_thread_flag(TIF_FOREIGN_FPSTATE); |
---|
943 | 960 | |
---|
944 | 961 | local_bh_enable(); |
---|
| 962 | + preempt_enable(); |
---|
| 963 | + kfree(mem); |
---|
945 | 964 | } |
---|
946 | 965 | |
---|
947 | 966 | /* |
---|
.. | .. |
---|
953 | 972 | if (!system_supports_fpsimd()) |
---|
954 | 973 | return; |
---|
955 | 974 | |
---|
| 975 | + preempt_disable(); |
---|
956 | 976 | local_bh_disable(); |
---|
957 | 977 | fpsimd_save(); |
---|
958 | 978 | local_bh_enable(); |
---|
| 979 | + preempt_enable(); |
---|
959 | 980 | } |
---|
960 | 981 | |
---|
961 | 982 | /* |
---|
.. | .. |
---|
1026 | 1047 | return; |
---|
1027 | 1048 | } |
---|
1028 | 1049 | |
---|
| 1050 | + preempt_disable(); |
---|
1029 | 1051 | local_bh_disable(); |
---|
1030 | 1052 | |
---|
1031 | 1053 | if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) { |
---|
.. | .. |
---|
1034 | 1056 | } |
---|
1035 | 1057 | |
---|
1036 | 1058 | local_bh_enable(); |
---|
| 1059 | + preempt_enable(); |
---|
1037 | 1060 | } |
---|
1038 | 1061 | |
---|
1039 | 1062 | /* |
---|
.. | .. |
---|
1046 | 1069 | if (WARN_ON(!system_supports_fpsimd())) |
---|
1047 | 1070 | return; |
---|
1048 | 1071 | |
---|
| 1072 | + preempt_disable(); |
---|
1049 | 1073 | local_bh_disable(); |
---|
1050 | 1074 | |
---|
1051 | 1075 | current->thread.uw.fpsimd_state = *state; |
---|
.. | .. |
---|
1058 | 1082 | clear_thread_flag(TIF_FOREIGN_FPSTATE); |
---|
1059 | 1083 | |
---|
1060 | 1084 | local_bh_enable(); |
---|
| 1085 | + preempt_enable(); |
---|
1061 | 1086 | } |
---|
1062 | 1087 | |
---|
1063 | 1088 | /* |
---|
.. | .. |
---|
1104 | 1129 | |
---|
1105 | 1130 | BUG_ON(!may_use_simd()); |
---|
1106 | 1131 | |
---|
| 1132 | + preempt_disable(); |
---|
1107 | 1133 | local_bh_disable(); |
---|
1108 | 1134 | |
---|
1109 | 1135 | __this_cpu_write(kernel_neon_busy, true); |
---|
.. | .. |
---|
1117 | 1143 | preempt_disable(); |
---|
1118 | 1144 | |
---|
1119 | 1145 | local_bh_enable(); |
---|
| 1146 | + preempt_enable(); |
---|
1120 | 1147 | } |
---|
1121 | 1148 | EXPORT_SYMBOL(kernel_neon_begin); |
---|
1122 | 1149 | |
---|