hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
kernel/arch/arm64/kernel/fpsimd.c
....@@ -159,6 +159,16 @@
159159 __sve_free(task);
160160 }
161161
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
+
162172 /*
163173 * TIF_SVE controls whether a task can use SVE without trapping while
164174 * in userspace, and also the way a task's FPSIMD/SVE state is stored
....@@ -549,6 +559,7 @@
549559 * non-SVE thread.
550560 */
551561 if (task == current) {
562
+ preempt_disable();
552563 local_bh_disable();
553564
554565 fpsimd_save();
....@@ -559,8 +570,10 @@
559570 if (test_and_clear_tsk_thread_flag(task, TIF_SVE))
560571 sve_to_fpsimd(task);
561572
562
- if (task == current)
573
+ if (task == current) {
563574 local_bh_enable();
575
+ preempt_enable();
576
+ }
564577
565578 /*
566579 * Force reallocation of task SVE state to the correct size
....@@ -815,6 +828,7 @@
815828
816829 sve_alloc(current);
817830
831
+ preempt_disable();
818832 local_bh_disable();
819833
820834 fpsimd_save();
....@@ -828,6 +842,7 @@
828842 WARN_ON(1); /* SVE access shouldn't have trapped */
829843
830844 local_bh_enable();
845
+ preempt_enable();
831846 }
832847
833848 /*
....@@ -894,10 +909,12 @@
894909 void fpsimd_flush_thread(void)
895910 {
896911 int vl, supported_vl;
912
+ void *mem = NULL;
897913
898914 if (!system_supports_fpsimd())
899915 return;
900916
917
+ preempt_disable();
901918 local_bh_disable();
902919
903920 memset(&current->thread.uw.fpsimd_state, 0,
....@@ -906,7 +923,7 @@
906923
907924 if (system_supports_sve()) {
908925 clear_thread_flag(TIF_SVE);
909
- sve_free(current);
926
+ mem = sve_free_atomic(current);
910927
911928 /*
912929 * Reset the task vector length as required.
....@@ -942,6 +959,8 @@
942959 set_thread_flag(TIF_FOREIGN_FPSTATE);
943960
944961 local_bh_enable();
962
+ preempt_enable();
963
+ kfree(mem);
945964 }
946965
947966 /*
....@@ -953,9 +972,11 @@
953972 if (!system_supports_fpsimd())
954973 return;
955974
975
+ preempt_disable();
956976 local_bh_disable();
957977 fpsimd_save();
958978 local_bh_enable();
979
+ preempt_enable();
959980 }
960981
961982 /*
....@@ -1026,6 +1047,7 @@
10261047 return;
10271048 }
10281049
1050
+ preempt_disable();
10291051 local_bh_disable();
10301052
10311053 if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) {
....@@ -1034,6 +1056,7 @@
10341056 }
10351057
10361058 local_bh_enable();
1059
+ preempt_enable();
10371060 }
10381061
10391062 /*
....@@ -1046,6 +1069,7 @@
10461069 if (WARN_ON(!system_supports_fpsimd()))
10471070 return;
10481071
1072
+ preempt_disable();
10491073 local_bh_disable();
10501074
10511075 current->thread.uw.fpsimd_state = *state;
....@@ -1058,6 +1082,7 @@
10581082 clear_thread_flag(TIF_FOREIGN_FPSTATE);
10591083
10601084 local_bh_enable();
1085
+ preempt_enable();
10611086 }
10621087
10631088 /*
....@@ -1104,6 +1129,7 @@
11041129
11051130 BUG_ON(!may_use_simd());
11061131
1132
+ preempt_disable();
11071133 local_bh_disable();
11081134
11091135 __this_cpu_write(kernel_neon_busy, true);
....@@ -1117,6 +1143,7 @@
11171143 preempt_disable();
11181144
11191145 local_bh_enable();
1146
+ preempt_enable();
11201147 }
11211148 EXPORT_SYMBOL(kernel_neon_begin);
11221149