Skip to content

Commit f8559b7

Browse files
authored
Merge pull request #6351 from douzzer/20230427-linuxkm-simd-fixes
20230427-linuxkm-simd-fixes
2 parents e4bf1a7 + 448f1ec commit f8559b7

4 files changed

Lines changed: 166 additions & 114 deletions

File tree

configure.ac

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8634,8 +8634,8 @@ fi
86348634

86358635
if test "$ENABLED_REPRODUCIBLE_BUILD" != "yes"
86368636
then
8637-
echo "#define LIBWOLFSSL_CONFIGURE_ARGS \"$ac_configure_args\"" > "${output_objdir}/.build_params" &&
8638-
echo "#define LIBWOLFSSL_GLOBAL_CFLAGS \"$CPPFLAGS $AM_CPPFLAGS $CFLAGS $AM_CFLAGS\" LIBWOLFSSL_GLOBAL_EXTRA_CFLAGS" >> "${output_objdir}/.build_params" ||
8637+
echo "#define LIBWOLFSSL_CONFIGURE_ARGS \"$ac_configure_args\"" | sed 's/\\/\\\\/g' > "${output_objdir}/.build_params" &&
8638+
echo "#define LIBWOLFSSL_GLOBAL_CFLAGS \"$CPPFLAGS $AM_CPPFLAGS $CFLAGS $AM_CFLAGS\" LIBWOLFSSL_GLOBAL_EXTRA_CFLAGS" | sed 's/\\/\\\\/g' >> "${output_objdir}/.build_params" ||
86398639
AC_MSG_ERROR([Couldn't create ${output_objdir}/.build_params.])
86408640
else
86418641
rm -f "${output_objdir}/.build_params"
@@ -8680,8 +8680,9 @@ for option in $CPPFLAGS $AM_CPPFLAGS $CFLAGS $AM_CFLAGS; do
86808680
opt_type=$(echo $option | $TRIM )
86818681
case "$opt_type" in
86828682
-D)
8683-
RHS_only=$(echo $option | sed 's/^-D//')
8684-
noequalsign=$(echo $RHS_only | sed 's/=/ /')
8683+
option=$(echo "$option" | tr -d '\\')
8684+
RHS_only=$(echo "$option" | sed 's/^-D//')
8685+
noequalsign=$(echo "$RHS_only" | tr '=' ' ')
86858686
if test "$noequalsign" = "NDEBUG" || test "$noequalsign" = "DEBUG"
86868687
then
86878688
if test "$verbose" = "yes"; then
@@ -8697,7 +8698,9 @@ for option in $CPPFLAGS $AM_CPPFLAGS $CFLAGS $AM_CFLAGS; do
86978698
echo "#ifndef WOLFSSL_OPTIONS_IGNORE_SYS" >> $OPTION_FILE
86988699
fi
86998700

8700-
noarg=$(echo "$RHS_only" | sed 's/=.*//')
8701+
# note need to use both autotools-style [] quoting and shell-style ''
8702+
# quoting for sed script with [] character set expression here.
8703+
noarg=$(echo "$RHS_only" | sed ['s/\(([^=)]*)\)\{0,1\}=.*//'])
87018704
echo "#undef $noarg" >> $OPTION_FILE
87028705
echo "#define $noequalsign" >> $OPTION_FILE
87038706

linuxkm/linuxkm_memory.c

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#endif
3131
#else
3232
static unsigned int *wolfcrypt_linuxkm_fpu_states = NULL;
33+
#define WC_FPU_COUNT_MASK 0x7fffffffU
34+
#define WC_FPU_SAVED_MASK 0x80000000U
3335
#endif
3436

3537
static WARN_UNUSED_RESULT inline int am_in_hard_interrupt_handler(void)
@@ -223,8 +225,10 @@
223225
*/
224226
((unsigned char *)wolfcrypt_linuxkm_fpu_states[processor_id])[PAGE_SIZE-1] = 1;
225227
#else /* !LINUXKM_SIMD_IRQ */
226-
if (wolfcrypt_linuxkm_fpu_states[processor_id] != 0) {
227-
if (wolfcrypt_linuxkm_fpu_states[processor_id] == ~0U) {
228+
if (wolfcrypt_linuxkm_fpu_states[processor_id] != 0U) {
229+
if ((wolfcrypt_linuxkm_fpu_states[processor_id] & WC_FPU_COUNT_MASK)
230+
== WC_FPU_COUNT_MASK)
231+
{
228232
preempt_enable();
229233
pr_err("save_vector_registers_x86 recursion register overflow for "
230234
"cpu id %d.\n", processor_id);
@@ -234,11 +238,28 @@
234238
return 0;
235239
}
236240
}
237-
kernel_fpu_begin();
238-
preempt_enable(); /* kernel_fpu_begin() does its own
239-
* preempt_disable(). decrement ours.
240-
*/
241-
wolfcrypt_linuxkm_fpu_states[processor_id] = 1;
241+
242+
/* if kernel_fpu_begin() won't actually save the reg file (because
243+
* it was already saved and invalidated, or because we're in a
244+
* kernel thread), don't call kernel_fpu_begin() here, nor call
245+
* kernel_fpu_end() in cleanup. this avoids pointless overhead. in
246+
* kernels >=5.17.12 (from changes to irq_fpu_usable() in linux
247+
* commit 59f5ede3bc0f, backported somewhere >5.17.5), this also
248+
* fixes register corruption.
249+
*/
250+
if ((current->flags & PF_KTHREAD) ||
251+
test_thread_flag(TIF_NEED_FPU_LOAD))
252+
{
253+
wolfcrypt_linuxkm_fpu_states[processor_id] =
254+
WC_FPU_SAVED_MASK + 1U; /* set msb 1 to inhibit kernel_fpu_end() at cleanup. */
255+
/* keep preempt_disable()d from above. */
256+
} else {
257+
kernel_fpu_begin();
258+
preempt_enable(); /* kernel_fpu_begin() does its own
259+
* preempt_disable(). decrement ours.
260+
*/
261+
wolfcrypt_linuxkm_fpu_states[processor_id] = 1U; /* set msb 0 to trigger kernel_fpu_end() at cleanup. */
262+
}
242263
#endif /* !LINUXKM_SIMD_IRQ */
243264

244265
return 0;
@@ -287,19 +308,29 @@
287308
kernel_fpu_end();
288309
}
289310
#else /* !LINUXKM_SIMD_IRQ */
290-
if (wolfcrypt_linuxkm_fpu_states[processor_id] == 0)
311+
if ((wolfcrypt_linuxkm_fpu_states[processor_id] & WC_FPU_COUNT_MASK) == 0U)
291312
{
292313
pr_err("restore_vector_registers_x86 called for cpu id %d "
293314
"without saved context.\n", processor_id);
294315
return;
295316
}
296317

297-
if (--wolfcrypt_linuxkm_fpu_states[processor_id] > 0) {
298-
preempt_enable(); /* preempt_disable count will still be nonzero after this decrement. */
318+
if ((--wolfcrypt_linuxkm_fpu_states[processor_id] & WC_FPU_COUNT_MASK) > 0U) {
319+
preempt_enable(); /* preempt_disable count may still be nonzero
320+
* after this decrement, but any remaining
321+
* count(s) aren't ours.
322+
*/
299323
return;
300324
}
301325

302-
kernel_fpu_end();
326+
if (wolfcrypt_linuxkm_fpu_states[processor_id] == 0U) {
327+
kernel_fpu_end();
328+
} else {
329+
preempt_enable(); /* preempt_disable count will still be nonzero
330+
* after this decrement.
331+
*/
332+
wolfcrypt_linuxkm_fpu_states[processor_id] = 0U;
333+
}
303334
#endif /* !LINUXKM_SIMD_IRQ */
304335

305336
return;

wolfcrypt/src/memory.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
#include <config.h>
2525
#endif
2626

27+
#ifdef WOLFSSL_LINUXKM
28+
#define WOLFSSL_NEED_LINUX_CURRENT
29+
#endif
30+
2731
#include <wolfssl/wolfcrypt/settings.h>
2832

2933
/* check old macros @wc_fips */

0 commit comments

Comments
 (0)