@@ -1073,17 +1073,17 @@ static inline struct wc_rng_inst *get_drbg(struct crypto_rng *tfm) {
10731073 return NULL ;
10741074 }
10751075
1076- #if defined(CONFIG_SMP ) && !defined(CONFIG_PREEMPT_COUNT ) && \
1077- (LINUX_VERSION_CODE >= KERNEL_VERSION (5 , 7 , 0 ))
10781076 if (tfm == crypto_default_rng ) {
1077+ #if defined(CONFIG_SMP ) && (LINUX_VERSION_CODE >= KERNEL_VERSION (5 , 7 , 0 ))
10791078 migrate_disable (); /* this actually makes irq_count() nonzero, so that
10801079 * DISABLE_VECTOR_REGISTERS() is superfluous, but
10811080 * don't depend on that.
10821081 */
1082+ #endif
1083+ local_bh_disable ();
10831084 new_lock_value = 2 ;
10841085 }
10851086 else
1086- #endif
10871087 {
10881088 new_lock_value = 1 ;
10891089 }
@@ -1104,7 +1104,9 @@ static inline struct wc_rng_inst *get_drbg(struct crypto_rng *tfm) {
11041104}
11051105
11061106/* get_drbg_n() is used by bulk seed, mix-in, and reseed operations. It expects
1107- * the caller to be able to wait until the requested DRBG is available.
1107+ * the caller to be able to wait until the requested DRBG is available. If the
1108+ * caller can't sleep and the requested DRBG is busy, it returns immediately --
1109+ * this avoids priority inversions and deadlocks.
11081110 */
11091111static inline struct wc_rng_inst * get_drbg_n (struct wc_linuxkm_drbg_ctx * ctx , int n ) {
11101112 int can_sleep = (preempt_count () == 0 );
@@ -1119,23 +1121,22 @@ static inline struct wc_rng_inst *get_drbg_n(struct wc_linuxkm_drbg_ctx *ctx, in
11191121 cond_resched ();
11201122 }
11211123 else
1122- cpu_relax () ;
1124+ return NULL ;
11231125 }
11241126
11251127 __builtin_unreachable ();
11261128}
11271129
11281130static inline void put_drbg (struct wc_rng_inst * drbg ) {
1129- #if defined(CONFIG_SMP ) && !defined(CONFIG_PREEMPT_COUNT ) && \
1130- (LINUX_VERSION_CODE >= KERNEL_VERSION (5 , 7 , 0 ))
11311131 int migration_disabled = (drbg -> lock == 2 );
1132- #endif
11331132 __atomic_store_n (& (drbg -> lock ),0 ,__ATOMIC_RELEASE );
1134- #if defined(CONFIG_SMP ) && !defined(CONFIG_PREEMPT_COUNT ) && \
1135- (LINUX_VERSION_CODE >= KERNEL_VERSION (5 , 7 , 0 ))
1136- if (migration_disabled )
1133+
1134+ if (migration_disabled ) {
1135+ local_bh_enable ();
1136+ #if defined(CONFIG_SMP ) && (LINUX_VERSION_CODE >= KERNEL_VERSION (5 , 7 , 0 ))
11371137 migrate_enable ();
1138- #endif
1138+ #endif
1139+ }
11391140}
11401141
11411142static int wc_linuxkm_drbg_generate (struct crypto_rng * tfm ,
0 commit comments