peerlookup: fall back to get_random_bytes for Ryzen 3000 bug

In case get_random_u32() fails after 32 tries -- something that should
only happen on the Ryzen 3000 which returns -1 everytime if you have the
wrong CPU microcode -- we fall back to get_random_bytes(), which is
slower, but at least works.
This commit is contained in:
Jason A. Donenfeld 2019-10-28 17:55:33 +01:00
parent 0b27b1d315
commit 719f1dc201
1 changed files with 5 additions and 1 deletions

View File

@ -120,6 +120,7 @@ __le32 wg_index_hashtable_insert(struct index_hashtable *table,
struct index_hashtable_entry *entry)
{
struct index_hashtable_entry *existing_entry;
unsigned int tries = 0;
spin_lock_bh(&table->lock);
hlist_del_init_rcu(&entry->index_hash);
@ -129,7 +130,10 @@ __le32 wg_index_hashtable_insert(struct index_hashtable *table,
search_unused_slot:
/* First we try to find an unused slot, randomly, while unlocked. */
entry->index = (__force __le32)get_random_u32();
if (++tries > 32) /* Work around AMD Ryzen 3000 RDRAND bug. */
get_random_bytes(&entry->index, sizeof(entry->index));
else
entry->index = (__force __le32)get_random_u32();
hlist_for_each_entry_rcu_bh(existing_entry,
index_bucket(table, entry->index),
index_hash) {