From fcf6ccd77107d64301a30f8d66583dbccd1ac217 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 26 Dec 2021 14:31:45 +0100 Subject: [PATCH] Kernel: Make KernelRng not inherit from Lockable This class was misusing the outdate Lockable template and didn't take advantage of the lock/resource separation mechanism fully anyway. Since the underlying PRNG has its own SpinLock, and we already use that for synchronization everywhere anyway, we can simply remove the Lockable inheritance from this class. --- Kernel/Random.cpp | 21 ++++++++++----------- Kernel/Random.h | 7 ++----- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/Kernel/Random.cpp b/Kernel/Random.cpp index 1889245991..fedb562c19 100644 --- a/Kernel/Random.cpp +++ b/Kernel/Random.cpp @@ -30,7 +30,7 @@ UNMAP_AFTER_INIT KernelRng::KernelRng() bool supports_rdrand = Processor::current().has_feature(CPUFeature::RDRAND); if (supports_rdseed || supports_rdrand) { dmesgln("KernelRng: Using RDSEED or RDRAND as entropy source"); - for (size_t i = 0; i < resource().pool_count * resource().reseed_threshold; ++i) { + for (size_t i = 0; i < pool_count * reseed_threshold; ++i) { u32 value = 0; if (supports_rdseed) { asm volatile( @@ -46,22 +46,22 @@ UNMAP_AFTER_INIT KernelRng::KernelRng() : "=r"(value)); } - this->resource().add_random_event(value, i % 32); + add_random_event(value, i % 32); } } else if (TimeManagement::the().can_query_precise_time()) { // Add HPET as entropy source if we don't have anything better. dmesgln("KernelRng: Using HPET as entropy source"); - for (size_t i = 0; i < resource().pool_count * resource().reseed_threshold; ++i) { + for (size_t i = 0; i < pool_count * reseed_threshold; ++i) { u64 hpet_time = HPET::the().read_main_counter_unsafe(); - this->resource().add_random_event(hpet_time, i % 32); + add_random_event(hpet_time, i % 32); } } else { // Fallback to RTC dmesgln("KernelRng: Using RTC as entropy source (bad!)"); auto current_time = static_cast(RTC::now()); - for (size_t i = 0; i < resource().pool_count * resource().reseed_threshold; ++i) { - this->resource().add_random_event(current_time, i % 32); + for (size_t i = 0; i < pool_count * reseed_threshold; ++i) { + add_random_event(current_time, i % 32); current_time *= 0x574au; current_time += 0x40b2u; } @@ -71,7 +71,7 @@ UNMAP_AFTER_INIT KernelRng::KernelRng() void KernelRng::wait_for_entropy() { SpinlockLocker lock(get_lock()); - if (!resource().is_ready()) { + if (!is_ready()) { dbgln("Entropy starvation..."); m_seed_queue.wait_forever("KernelRng"); } @@ -80,7 +80,7 @@ void KernelRng::wait_for_entropy() void KernelRng::wake_if_ready() { VERIFY(get_lock().is_locked()); - if (resource().is_ready()) { + if (is_ready()) { m_seed_queue.wake_all(); } } @@ -126,8 +126,7 @@ bool get_good_random_bytes(Bytes buffer, bool allow_wait, bool fallback_to_fast) if (can_wait && allow_wait) { for (;;) { { - MutexLocker locker(KernelRng::the().lock()); - if (kernel_rng.resource().get_random_bytes(buffer)) { + if (kernel_rng.get_random_bytes(buffer)) { result = true; break; } @@ -136,7 +135,7 @@ bool get_good_random_bytes(Bytes buffer, bool allow_wait, bool fallback_to_fast) } } else { // We can't wait/block here, or we are not allowed to block/wait - if (kernel_rng.resource().get_random_bytes(buffer)) { + if (kernel_rng.get_random_bytes(buffer)) { result = true; } else if (fallback_to_fast) { // If interrupts are disabled diff --git a/Kernel/Random.h b/Kernel/Random.h index d2b9e96c7d..dc7ae70436 100644 --- a/Kernel/Random.h +++ b/Kernel/Random.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -120,7 +119,7 @@ private: Spinlock m_lock; }; -class KernelRng : public Lockable> { +class KernelRng : public FortunaPRNG { AK_MAKE_ETERNAL; public: @@ -131,8 +130,6 @@ public: void wake_if_ready(); - Spinlock& get_lock() { return resource().get_lock(); } - private: WaitQueue m_seed_queue; }; @@ -168,7 +165,7 @@ public: SpinlockLocker lock(kernel_rng.get_lock()); // We don't lock this because on the off chance a pool is corrupted, entropy isn't lost. Event event = { read_tsc(), m_source, event_data }; - kernel_rng.resource().add_random_event(event, m_pool); + kernel_rng.add_random_event(event, m_pool); m_pool++; kernel_rng.wake_if_ready(); }