Skip to content

Commit cc2f792

Browse files
authored
Merge pull request #9035 from douzzer/20250725-wc_linuxkm_relax_long_loop
20250725-wc_linuxkm_relax_long_loop
2 parents c347f75 + b0f6829 commit cc2f792

File tree

16 files changed

+165
-25
lines changed

16 files changed

+165
-25
lines changed

.wolfssl_known_macro_extras

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ CONFIG_POSIX_API
127127
CONFIG_POSIX_THREADS
128128
CONFIG_PREEMPT_COUNT
129129
CONFIG_PTHREAD_IPC
130+
CONFIG_SCHED_INFO
130131
CONFIG_SMP
131132
CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH
132133
CONFIG_TIMER_TASK_STACK_DEPTH

linuxkm/linuxkm_wc_port.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,15 @@
126126
extern int wc_lkm_LockMutex(struct wolfSSL_Mutex* m);
127127
#endif
128128

129+
#ifndef WC_LINUXKM_INTR_SIGNALS
130+
#define WC_LINUXKM_INTR_SIGNALS { SIGKILL, SIGABRT, SIGHUP, SIGINT }
131+
#endif
132+
extern int wc_linuxkm_check_for_intr_signals(void);
133+
#ifndef WC_LINUXKM_MAX_NS_WITHOUT_YIELD
134+
#define WC_LINUXKM_MAX_NS_WITHOUT_YIELD 1000000000
135+
#endif
136+
extern void wc_linuxkm_relax_long_loop(void);
137+
129138
#ifdef BUILDING_WOLFSSL
130139

131140
#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)) || \
@@ -351,6 +360,8 @@
351360
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
352361
/* for signal_pending() */
353362
#include <linux/sched/signal.h>
363+
/* for local_clock() */
364+
#include <linux/sched/clock.h>
354365
#endif
355366
#include <linux/random.h>
356367

@@ -424,6 +435,13 @@
424435
#endif
425436
#endif
426437

438+
#ifndef WC_CHECK_FOR_INTR_SIGNALS
439+
#define WC_CHECK_FOR_INTR_SIGNALS() wc_linuxkm_check_for_intr_signals()
440+
#endif
441+
#ifndef WC_RELAX_LONG_LOOP
442+
#define WC_RELAX_LONG_LOOP() wc_linuxkm_relax_long_loop()
443+
#endif
444+
427445
/* benchmarks.c uses floating point math, so needs a working
428446
* SAVE_VECTOR_REGISTERS().
429447
*/
@@ -875,6 +893,9 @@
875893
typeof(wc_lkm_LockMutex) *wc_lkm_LockMutex;
876894
#endif
877895

896+
typeof(wc_linuxkm_check_for_intr_signals) *wc_linuxkm_check_for_intr_signals;
897+
typeof(wc_linuxkm_relax_long_loop) *wc_linuxkm_relax_long_loop;
898+
878899
const void *_last_slot;
879900
};
880901

@@ -1099,6 +1120,9 @@
10991120
*/
11001121
#define spin_unlock_irqrestore(lock, flags) raw_spin_unlock_irqrestore(&((lock)->rlock), flags)
11011122

1123+
#define wc_linuxkm_check_for_intr_signals WC_LKM_INDIRECT_SYM(wc_linuxkm_check_for_intr_signals)
1124+
#define wc_linuxkm_relax_long_loop WC_LKM_INDIRECT_SYM(wc_linuxkm_relax_long_loop)
1125+
11021126
#endif /* __PIE__ */
11031127

11041128
#endif /* USE_WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE */

linuxkm/lkcapi_glue.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ static int linuxkm_lkcapi_sysfs_deinstall(void) {
310310
return 0;
311311
}
312312

313+
static volatile int linuxkm_lkcapi_registering_now = 0;
313314
static int linuxkm_lkcapi_registered = 0;
314315
static int linuxkm_lkcapi_n_registered = 0;
315316

@@ -318,9 +319,11 @@ static int linuxkm_lkcapi_register(void)
318319
int ret = -1;
319320
int seen_err = 0;
320321

322+
linuxkm_lkcapi_registering_now = 1;
323+
321324
ret = linuxkm_lkcapi_sysfs_install();
322325
if (ret)
323-
return ret;
326+
goto out;
324327

325328
#if defined(CONFIG_CRYPTO_MANAGER_EXTRA_TESTS) || \
326329
defined(CONFIG_CRYPTO_SELFTESTS_FULL)
@@ -704,20 +707,30 @@ static int linuxkm_lkcapi_register(void)
704707

705708
if (ret == -1) {
706709
/* no installations occurred */
707-
if (linuxkm_lkcapi_registered)
708-
return -EEXIST;
710+
if (linuxkm_lkcapi_registered) {
711+
ret = -EEXIST;
712+
goto out;
713+
}
709714
else {
710715
linuxkm_lkcapi_registered = 1;
711-
return 0;
716+
ret = 0;
717+
goto out;
712718
}
713719
}
714720
else {
715721
/* flag that linuxkm_lkcapi_register has been called, even if an error
716722
* occurred.
717723
*/
718724
linuxkm_lkcapi_registered = 1;
719-
return seen_err;
725+
ret = seen_err;
726+
goto out;
720727
}
728+
729+
out:
730+
731+
linuxkm_lkcapi_registering_now = 0;
732+
733+
return ret;
721734
}
722735

723736
static int linuxkm_lkcapi_unregister(void)

linuxkm/module_hooks.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,66 @@ WC_MAYBE_UNUSED static int linuxkm_lkcapi_sysfs_deinstall_node(struct kobj_attri
198198
#include "linuxkm/lkcapi_glue.c"
199199
#endif
200200

201+
int wc_linuxkm_check_for_intr_signals(void) {
202+
static const int intr_signals[] = WC_LINUXKM_INTR_SIGNALS;
203+
if (preempt_count() != 0)
204+
return 0;
205+
206+
#if defined(HAVE_FIPS) && defined(LINUXKM_LKCAPI_REGISTER)
207+
/* ignore signals during FIPS startup sequence -- failed alg tests cause
208+
* kernel panics on FIPS kernels.
209+
*/
210+
if (linuxkm_lkcapi_registering_now)
211+
return 0;
212+
#endif
213+
if (signal_pending(current)) {
214+
int i;
215+
for (i = 0;
216+
i < (int)sizeof(intr_signals) / (int)sizeof(intr_signals[0]);
217+
++i)
218+
{
219+
if (sigismember(&current->pending.signal, intr_signals[i])) {
220+
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
221+
pr_err("INFO: wc_linuxkm_check_for_intr_signals returning "
222+
"INTERRUPTED_E on signal %d\n", intr_signals[i]);
223+
#endif
224+
return INTERRUPTED_E;
225+
}
226+
}
227+
}
228+
return 0;
229+
}
230+
231+
void wc_linuxkm_relax_long_loop(void) {
232+
#if WC_LINUXKM_MAX_NS_WITHOUT_YIELD >= 0
233+
if (preempt_count() == 0) {
234+
#if (WC_LINUXKM_MAX_NS_WITHOUT_YIELD == 0) || !defined(CONFIG_SCHED_INFO)
235+
cond_resched();
236+
#else
237+
/* note that local_clock() wraps a local_clock_noinstr() in a
238+
* preempt_disable_notrace(), which sounds expensive but isn't --
239+
* preempt_disable_notrace() is actually just a nonlocking integer
240+
* increment of current_thread_info()->preempt.count, protected only by
241+
* various compiler optimizer barriers.
242+
*/
243+
u64 now = local_clock();
244+
u64 current_last_arrival = current->sched_info.last_arrival;
245+
s64 delta = (s64)(now - current_last_arrival);
246+
if (delta > WC_LINUXKM_MAX_NS_WITHOUT_YIELD) {
247+
cond_resched();
248+
/* if nothing else is runnable, cond_resched() is a no-op and
249+
* doesn't even update .last_arrival. we could force update by
250+
* sleeping, but there's no need. we've been nice enough by just
251+
* cond_resched()ing, and it's actually preferable to call
252+
* cond_resched() frequently once computation has looped
253+
* continuously for longer than WC_LINUXKM_MAX_NS_WITHOUT_YIELD.
254+
*/
255+
}
256+
#endif
257+
}
258+
#endif
259+
}
260+
201261
#if defined(WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS) && defined(CONFIG_X86)
202262
#include "linuxkm/x86_vector_register_glue.c"
203263
#endif
@@ -745,6 +805,9 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) {
745805
wolfssl_linuxkm_pie_redirect_table.queued_spin_lock_slowpath = queued_spin_lock_slowpath;
746806
#endif
747807

808+
wolfssl_linuxkm_pie_redirect_table.wc_linuxkm_check_for_intr_signals = wc_linuxkm_check_for_intr_signals;
809+
wolfssl_linuxkm_pie_redirect_table.wc_linuxkm_relax_long_loop = wc_linuxkm_relax_long_loop;
810+
748811
/* runtime assert that the table has no null slots after initialization. */
749812
{
750813
unsigned long *i;

linuxkm/x86_vector_register_glue.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,14 @@ WARN_UNUSED_RESULT int save_vector_registers_x86(enum wc_svr_flags flags)
372372
__builtin_unreachable();
373373
}
374374

375+
{
376+
int ret = WC_CHECK_FOR_INTR_SIGNALS();
377+
if (ret)
378+
return ret;
379+
}
380+
381+
WC_RELAX_LONG_LOOP();
382+
375383
if (flags & WC_SVR_FLAG_INHIBIT) {
376384
if ((preempt_count() != 0) && !may_use_simd())
377385
return WC_ACCEL_INHIBIT_E; /* not an error here, just a
@@ -507,5 +515,7 @@ void restore_vector_registers_x86(void)
507515
migrate_enable();
508516
#endif
509517

518+
WC_RELAX_LONG_LOOP();
519+
510520
return;
511521
}

wolfcrypt/src/curve25519.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@
6060
#if defined(WOLFSSL_LINUXKM) && !defined(USE_INTEL_SPEEDUP)
6161
/* force off unneeded vector register save/restore. */
6262
#undef SAVE_VECTOR_REGISTERS
63-
#define SAVE_VECTOR_REGISTERS(fail_clause) WC_DO_NOTHING
63+
#define SAVE_VECTOR_REGISTERS(fail_clause) SAVE_NO_VECTOR_REGISTERS(fail_clause)
6464
#undef RESTORE_VECTOR_REGISTERS
65-
#define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING
65+
#define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
6666
#endif
6767

6868
const curve25519_set_type curve25519_sets[] = {

wolfcrypt/src/dh.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@
6060
#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM)
6161
/* force off unneeded vector register save/restore. */
6262
#undef SAVE_VECTOR_REGISTERS
63-
#define SAVE_VECTOR_REGISTERS(fail_clause) WC_DO_NOTHING
63+
#define SAVE_VECTOR_REGISTERS(fail_clause) SAVE_NO_VECTOR_REGISTERS(fail_clause)
6464
#undef RESTORE_VECTOR_REGISTERS
65-
#define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING
65+
#define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
6666
#endif
6767

6868
/*

wolfcrypt/src/dsa.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@
3838
#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM)
3939
/* force off unneeded vector register save/restore. */
4040
#undef SAVE_VECTOR_REGISTERS
41-
#define SAVE_VECTOR_REGISTERS(fail_clause) WC_DO_NOTHING
41+
#define SAVE_VECTOR_REGISTERS(fail_clause) SAVE_NO_VECTOR_REGISTERS(fail_clause)
4242
#undef RESTORE_VECTOR_REGISTERS
43-
#define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING
43+
#define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
4444
#endif
4545

4646
#ifdef _MSC_VER

wolfcrypt/src/ecc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,9 @@ ECC Curve Sizes:
224224
#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM)
225225
/* force off unneeded vector register save/restore. */
226226
#undef SAVE_VECTOR_REGISTERS
227-
#define SAVE_VECTOR_REGISTERS(fail_clause) WC_DO_NOTHING
227+
#define SAVE_VECTOR_REGISTERS(fail_clause) SAVE_NO_VECTOR_REGISTERS(fail_clause)
228228
#undef RESTORE_VECTOR_REGISTERS
229-
#define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING
229+
#define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
230230
#endif
231231

232232
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \

wolfcrypt/src/eccsi.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@
3939
#if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM)
4040
/* force off unneeded vector register save/restore. */
4141
#undef SAVE_VECTOR_REGISTERS
42-
#define SAVE_VECTOR_REGISTERS(fail_clause) WC_DO_NOTHING
42+
#define SAVE_VECTOR_REGISTERS(fail_clause) SAVE_NO_VECTOR_REGISTERS(fail_clause)
4343
#undef RESTORE_VECTOR_REGISTERS
44-
#define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING
44+
#define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
4545
#endif
4646

4747
#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV

0 commit comments

Comments
 (0)