@@ -175,10 +175,14 @@ void free_wolfcrypt_linuxkm_fpu_states(void) {
175175/* legacy thread-local storage facility for tracking recursive fpu
176176 * pushing/popping
177177 */
178- static struct wc_thread_fpu_count_ent * wc_linuxkm_fpu_state_assoc (int create_p ) {
178+ static struct wc_thread_fpu_count_ent * wc_linuxkm_fpu_state_assoc (
179+ int create_p , int assume_fpu_began )
180+ {
179181 struct wc_thread_fpu_count_ent * i , * i_endptr , * i_empty ;
180182 pid_t my_pid = task_pid_nr (current ), i_pid ;
181183
184+ (void )assume_fpu_began ;
185+
182186 {
183187 static int _warned_on_null = 0 ;
184188 if (wc_linuxkm_fpu_states == NULL )
@@ -330,7 +334,7 @@ static struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc_unlikely(int c
330334}
331335
332336static inline struct wc_thread_fpu_count_ent * wc_linuxkm_fpu_state_assoc (
333- int create_p )
337+ int create_p , int assume_fpu_began )
334338{
335339 int my_cpu = raw_smp_processor_id (); /* my_cpu is only trustworthy if we're
336340 * already nonpreemptible -- we'll
@@ -352,6 +356,12 @@ static inline struct wc_thread_fpu_count_ent *wc_linuxkm_fpu_state_assoc(
352356 else
353357 return slot ;
354358 }
359+ if (! assume_fpu_began ) {
360+ /* this was just a quick check for whether we're in a recursive
361+ * save_vector_registers_x86(). we're not.
362+ */
363+ return NULL ;
364+ }
355365 if (likely (create_p )) {
356366 if (likely (slot_pid == 0 )) {
357367 __atomic_store_n (& slot -> pid , my_pid , __ATOMIC_RELEASE );
@@ -407,7 +417,7 @@ WARN_UNUSED_RESULT int can_save_vector_registers_x86(void)
407417 * checking wc_linuxkm_fpu_states.
408418 */
409419
410- struct wc_thread_fpu_count_ent * pstate = wc_linuxkm_fpu_state_assoc (0 );
420+ struct wc_thread_fpu_count_ent * pstate = wc_linuxkm_fpu_state_assoc (0 , 0 );
411421
412422 if ((pstate != NULL ) && (pstate -> fpu_state != 0U )) {
413423 if (unlikely ((pstate -> fpu_state & WC_FPU_COUNT_MASK )
@@ -452,9 +462,9 @@ WARN_UNUSED_RESULT int can_save_vector_registers_x86(void)
452462WARN_UNUSED_RESULT int save_vector_registers_x86 (void )
453463{
454464#ifdef LINUXKM_FPU_STATES_FOLLOW_THREADS
455- struct wc_thread_fpu_count_ent * pstate = wc_linuxkm_fpu_state_assoc (1 );
465+ struct wc_thread_fpu_count_ent * pstate = wc_linuxkm_fpu_state_assoc (1 , 0 );
456466#else
457- struct wc_thread_fpu_count_ent * pstate = wc_linuxkm_fpu_state_assoc (0 );
467+ struct wc_thread_fpu_count_ent * pstate = wc_linuxkm_fpu_state_assoc (0 , 0 );
458468#endif
459469
460470 /* allow for nested calls */
@@ -520,7 +530,7 @@ WARN_UNUSED_RESULT int save_vector_registers_x86(void)
520530 kernel_fpu_begin ();
521531
522532#ifndef LINUXKM_FPU_STATES_FOLLOW_THREADS
523- pstate = wc_linuxkm_fpu_state_assoc (1 );
533+ pstate = wc_linuxkm_fpu_state_assoc (1 , 1 );
524534 if (pstate == NULL ) {
525535 kernel_fpu_end ();
526536 #if defined(CONFIG_SMP ) && !defined(CONFIG_PREEMPT_COUNT ) && \
@@ -561,7 +571,7 @@ WARN_UNUSED_RESULT int save_vector_registers_x86(void)
561571 migrate_disable ();
562572#endif
563573#ifndef LINUXKM_FPU_STATES_FOLLOW_THREADS
564- pstate = wc_linuxkm_fpu_state_assoc (1 );
574+ pstate = wc_linuxkm_fpu_state_assoc (1 , 1 );
565575 if (pstate == NULL ) {
566576 #if defined(CONFIG_SMP ) && !defined(CONFIG_PREEMPT_COUNT ) && \
567577 (LINUX_VERSION_CODE >= KERNEL_VERSION (5 , 7 , 0 )) && \
@@ -595,7 +605,7 @@ WARN_UNUSED_RESULT int save_vector_registers_x86(void)
595605
596606void restore_vector_registers_x86 (void )
597607{
598- struct wc_thread_fpu_count_ent * pstate = wc_linuxkm_fpu_state_assoc (0 );
608+ struct wc_thread_fpu_count_ent * pstate = wc_linuxkm_fpu_state_assoc (0 , 1 );
599609 if (unlikely (pstate == NULL )) {
600610 pr_err ("restore_vector_registers_x86 called by pid %d on CPU %d "
601611 "with no saved state.\n" , task_pid_nr (current ),
0 commit comments