@@ -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 ;
0 commit comments