Skip to content

Commit 43e68ad

Browse files
Merge pull request #8669 from douzzer/20250414-can_save_vector_registers_x86-recursive
20250414-can_save_vector_registers_x86-recursive
2 parents bbe956c + ecf9982 commit 43e68ad

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

.wolfssl_known_macro_extras

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ TCP_NODELAY
492492
TFM_ALREADY_SET
493493
TFM_SMALL_MONT_SET
494494
THREADED_SNIFFTEST
495+
TIF_NEED_FPU_LOAD
495496
TIME_T_NOT_LONG
496497
TI_DUMMY_BUILD
497498
TLS13_RSA_PSS_SIGN_CB_NO_PREHASH

linuxkm/x86_vector_register_glue.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,12 +400,34 @@ static inline void wc_linuxkm_fpu_state_release(
400400

401401
WARN_UNUSED_RESULT int can_save_vector_registers_x86(void)
402402
{
403+
/* First, check if we're already saved, per wc_linuxkm_fpu_states.
404+
*
405+
* On kernel >= 6.15, irq_fpu_usable() dumps a backtrace to the kernel log
406+
* if called while already saved, so it's crucial to preempt that call by
407+
* checking wc_linuxkm_fpu_states.
408+
*/
409+
410+
struct wc_thread_fpu_count_ent *pstate = wc_linuxkm_fpu_state_assoc(0);
411+
412+
if ((pstate != NULL) && (pstate->fpu_state != 0U)) {
413+
if (unlikely((pstate->fpu_state & WC_FPU_COUNT_MASK)
414+
== WC_FPU_COUNT_MASK))
415+
{
416+
/* would overflow */
417+
return 0;
418+
} else {
419+
return 1;
420+
}
421+
}
422+
403423
if (irq_fpu_usable())
404424
return 1;
405425
else if (in_nmi() || (hardirq_count() > 0) || (softirq_count() > 0))
406426
return 0;
427+
#ifdef TIF_NEED_FPU_LOAD
407428
else if (test_thread_flag(TIF_NEED_FPU_LOAD))
408429
return 1;
430+
#endif
409431
return 0;
410432
}
411433

@@ -441,7 +463,7 @@ WARN_UNUSED_RESULT int save_vector_registers_x86(void)
441463
}
442464

443465
if (irq_fpu_usable()
444-
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0))
466+
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0)) && defined(TIF_NEED_FPU_LOAD)
445467
/* work around a kernel bug -- see linux commit 59f5ede3bc0f0.
446468
* what we really want here is this_cpu_read(in_kernel_fpu), but
447469
* in_kernel_fpu is an unexported static array.
@@ -489,6 +511,7 @@ WARN_UNUSED_RESULT int save_vector_registers_x86(void)
489511
wc_linuxkm_fpu_state_release(pstate);
490512
#endif
491513
return BAD_STATE_E;
514+
#ifdef TIF_NEED_FPU_LOAD
492515
} else if (!test_thread_flag(TIF_NEED_FPU_LOAD)) {
493516
static int warned_fpu_forbidden = 0;
494517
if (! warned_fpu_forbidden)
@@ -498,6 +521,7 @@ WARN_UNUSED_RESULT int save_vector_registers_x86(void)
498521
wc_linuxkm_fpu_state_release(pstate);
499522
#endif
500523
return BAD_STATE_E;
524+
#endif
501525
} else {
502526
/* assume already safely in_kernel_fpu from caller, but recursively
503527
* preempt_disable() to be extra-safe.

0 commit comments

Comments
 (0)