@@ -990,6 +990,10 @@ static inline void wc_linuxkm_drbg_ctx_clear(struct wc_linuxkm_drbg_ctx * ctx)
990990
991991static volatile int wc_linuxkm_drbg_init_tfm_disable_vector_registers = 0 ;
992992
993+ #ifndef WC_LINUXKM_INITRNG_TIMEOUT_SEC
994+ #define WC_LINUXKM_INITRNG_TIMEOUT_SEC 30
995+ #endif
996+
993997static int wc_linuxkm_drbg_init_tfm (struct crypto_tfm * tfm )
994998{
995999 struct wc_linuxkm_drbg_ctx * ctx = (struct wc_linuxkm_drbg_ctx * )crypto_tfm_ctx (tfm );
@@ -1007,19 +1011,35 @@ static int wc_linuxkm_drbg_init_tfm(struct crypto_tfm *tfm)
10071011 XMEMSET (ctx -> rngs , 0 , sizeof (* ctx -> rngs ) * ctx -> n_rngs );
10081012
10091013 for (i = 0 ; i < ctx -> n_rngs ; ++ i ) {
1010- ctx -> rngs [i ].lock = 0 ;
1011- if (wc_linuxkm_drbg_init_tfm_disable_vector_registers )
1012- need_reenable_vec = (DISABLE_VECTOR_REGISTERS () == 0 );
1013- ret = wc_InitRng (& ctx -> rngs [i ].rng );
1014- if (need_reenable_vec )
1015- REENABLE_VECTOR_REGISTERS ();
1014+ int nretries = 0 ;
1015+ u64 ts1 = ktime_get_ns ();
1016+ for (;;) {
1017+ u64 ts2 ;
1018+ if (wc_linuxkm_drbg_init_tfm_disable_vector_registers )
1019+ need_reenable_vec = (DISABLE_VECTOR_REGISTERS () == 0 );
1020+ ret = wc_InitRng (& ctx -> rngs [i ].rng );
1021+ if (need_reenable_vec )
1022+ REENABLE_VECTOR_REGISTERS ();
1023+ if (can_sleep )
1024+ cond_resched ();
1025+ if (ret == 0 )
1026+ break ;
1027+ if (can_sleep ) {
1028+ if (WC_CHECK_FOR_INTR_SIGNALS () == INTERRUPTED_E ) {
1029+ ret = - EINTR ;
1030+ break ;
1031+ }
1032+ }
1033+ ts2 = ktime_get_ns ();
1034+ if (ts2 - ts1 > 1000000000L * WC_LINUXKM_INITRNG_TIMEOUT_SEC )
1035+ break ;
1036+ ++ nretries ;
1037+ }
10161038 if (ret != 0 ) {
1017- pr_warn_once ("WARNING: wc_InitRng returned %d\n" ,ret );
1039+ pr_warn ("WARNING: wc_InitRng returned %d after %d retries. \n" ,ret , nretries );
10181040 ret = - EINVAL ;
10191041 break ;
10201042 }
1021- if (can_sleep )
1022- cond_resched ();
10231043 }
10241044
10251045 if (ret != 0 ) {
0 commit comments