@@ -750,37 +750,42 @@ static int __init debug_boot_weak_hash_enable(char *str)
750
750
}
751
751
early_param ("debug_boot_weak_hash" , debug_boot_weak_hash_enable );
752
752
753
- static DEFINE_STATIC_KEY_FALSE (filled_random_ptr_key );
753
+ static bool filled_random_ptr_key __read_mostly ;
754
+ static siphash_key_t ptr_key __read_mostly ;
755
+ static void fill_ptr_key_workfn (struct work_struct * work );
756
+ static DECLARE_DELAYED_WORK (fill_ptr_key_work , fill_ptr_key_workfn );
754
757
755
- static void enable_ptr_key_workfn (struct work_struct * work )
758
+ static void fill_ptr_key_workfn (struct work_struct * work )
756
759
{
757
- static_branch_enable (& filled_random_ptr_key );
760
+ if (!rng_is_initialized ()) {
761
+ queue_delayed_work (system_unbound_wq , & fill_ptr_key_work , HZ * 2 );
762
+ return ;
763
+ }
764
+
765
+ get_random_bytes (& ptr_key , sizeof (ptr_key ));
766
+
767
+ /* Pairs with smp_rmb() before reading ptr_key. */
768
+ smp_wmb ();
769
+ WRITE_ONCE (filled_random_ptr_key , true);
770
+ }
771
+
772
+ static int __init vsprintf_init_hashval (void )
773
+ {
774
+ fill_ptr_key_workfn (NULL );
775
+ return 0 ;
758
776
}
777
+ subsys_initcall (vsprintf_init_hashval )
759
778
760
779
/* Maps a pointer to a 32 bit unique identifier. */
761
780
static inline int __ptr_to_hashval (const void * ptr , unsigned long * hashval_out )
762
781
{
763
- static siphash_key_t ptr_key __read_mostly ;
764
782
unsigned long hashval ;
765
783
766
- if (!static_branch_likely (& filled_random_ptr_key )) {
767
- static bool filled = false;
768
- static DEFINE_SPINLOCK (filling );
769
- static DECLARE_WORK (enable_ptr_key_work , enable_ptr_key_workfn );
770
- unsigned long flags ;
771
-
772
- if (!system_unbound_wq || !rng_is_initialized () ||
773
- !spin_trylock_irqsave (& filling , flags ))
774
- return - EAGAIN ;
775
-
776
- if (!filled ) {
777
- get_random_bytes (& ptr_key , sizeof (ptr_key ));
778
- queue_work (system_unbound_wq , & enable_ptr_key_work );
779
- filled = true;
780
- }
781
- spin_unlock_irqrestore (& filling , flags );
782
- }
784
+ if (!READ_ONCE (filled_random_ptr_key ))
785
+ return - EBUSY ;
783
786
787
+ /* Pairs with smp_wmb() after writing ptr_key. */
788
+ smp_rmb ();
784
789
785
790
#ifdef CONFIG_64BIT
786
791
hashval = (unsigned long )siphash_1u64 ((u64 )ptr , & ptr_key );
0 commit comments