diff options
| author | Takashi Iwai <tiwai@suse.de> | 2022-07-04 14:14:04 +0200 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2022-07-04 14:14:04 +0200 |
| commit | dd84cfff3cc3b79c9d616f85bd1178df135cbd1a (patch) | |
| tree | cd02e30a78211bed4f1270877b705a079d4bd364 /lib/vsprintf.c | |
| parent | 2307a0e1ca0b5c1337b37ac6302f96e017ebac3c (diff) | |
| parent | 980555e95f7cabdc9c80a07107622b097ba23703 (diff) | |
| download | lwn-dd84cfff3cc3b79c9d616f85bd1178df135cbd1a.tar.gz lwn-dd84cfff3cc3b79c9d616f85bd1178df135cbd1a.zip | |
Merge tag 'asoc-fix-v5.19-rc3' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v5.19
A collection of fixes for v5.19, quite large but nothing major - a good
chunk of it is more stuff that was identified by mixer-test regarding
event generation.
Diffstat (limited to 'lib/vsprintf.c')
| -rw-r--r-- | lib/vsprintf.c | 67 |
1 files changed, 22 insertions, 45 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 40d26a07a133..fb77f7bfd126 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -750,61 +750,38 @@ static int __init debug_boot_weak_hash_enable(char *str) } early_param("debug_boot_weak_hash", debug_boot_weak_hash_enable); -static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key); -static siphash_key_t ptr_key __read_mostly; +static DEFINE_STATIC_KEY_FALSE(filled_random_ptr_key); static void enable_ptr_key_workfn(struct work_struct *work) { - get_random_bytes(&ptr_key, sizeof(ptr_key)); - /* Needs to run from preemptible context */ - static_branch_disable(¬_filled_random_ptr_key); + static_branch_enable(&filled_random_ptr_key); } -static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); - -static int fill_random_ptr_key(struct notifier_block *nb, - unsigned long action, void *data) -{ - /* This may be in an interrupt handler. */ - queue_work(system_unbound_wq, &enable_ptr_key_work); - return 0; -} - -static struct notifier_block random_ready = { - .notifier_call = fill_random_ptr_key -}; - -static int __init initialize_ptr_random(void) -{ - int key_size = sizeof(ptr_key); - int ret; - - /* Use hw RNG if available. */ - if (get_random_bytes_arch(&ptr_key, key_size) == key_size) { - static_branch_disable(¬_filled_random_ptr_key); - return 0; - } - - ret = register_random_ready_notifier(&random_ready); - if (!ret) { - return 0; - } else if (ret == -EALREADY) { - /* This is in preemptible context */ - enable_ptr_key_workfn(&enable_ptr_key_work); - return 0; - } - - return ret; -} -early_initcall(initialize_ptr_random); - /* Maps a pointer to a 32 bit unique identifier. */ static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out) { + static siphash_key_t ptr_key __read_mostly; unsigned long hashval; - if (static_branch_unlikely(¬_filled_random_ptr_key)) - return -EAGAIN; + if (!static_branch_likely(&filled_random_ptr_key)) { + static bool filled = false; + static DEFINE_SPINLOCK(filling); + static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); + unsigned long flags; + + if (!system_unbound_wq || + (!rng_is_initialized() && !rng_has_arch_random()) || + !spin_trylock_irqsave(&filling, flags)) + return -EAGAIN; + + if (!filled) { + get_random_bytes(&ptr_key, sizeof(ptr_key)); + queue_work(system_unbound_wq, &enable_ptr_key_work); + filled = true; + } + spin_unlock_irqrestore(&filling, flags); + } + #ifdef CONFIG_64BIT hashval = (unsigned long)siphash_1u64((u64)ptr, &ptr_key); |
