summaryrefslogtreecommitdiff
path: root/Kernel/Arch/i386
diff options
context:
space:
mode:
authorJean-Baptiste Boric <jblbeurope@gmail.com>2021-01-24 18:17:54 +0100
committerAndreas Kling <kling@serenityos.org>2021-01-24 22:16:18 +0100
commit7eaefa5aa6b85f5f7720ee823da2969280994fcb (patch)
tree81a4fbb70c261e52b1d80e40e4c19c05a41dee9d /Kernel/Arch/i386
parentcb89d3b7804730ce0a1c3638231f5f9f4e28099d (diff)
downloadserenity-7eaefa5aa6b85f5f7720ee823da2969280994fcb.zip
Kernel: Make use of interrupts as an entropy source
Booting old computers without RDRAND/RDSEED and without a disk makes the system severely starved for entropy. Uses interrupts as a source to side-step that issue. Also warn whenever the system is starved of entropy, because that's a non-obvious failure mode.
Diffstat (limited to 'Kernel/Arch/i386')
-rw-r--r--Kernel/Arch/i386/CPU.cpp4
1 files changed, 4 insertions, 0 deletions
diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp
index da850af1c3..9a9e1a29af 100644
--- a/Kernel/Arch/i386/CPU.cpp
+++ b/Kernel/Arch/i386/CPU.cpp
@@ -44,6 +44,7 @@
#include <Kernel/Interrupts/UnhandledInterruptHandler.h>
#include <Kernel/KSyms.h>
#include <Kernel/Process.h>
+#include <Kernel/Random.h>
#include <Kernel/SpinLock.h>
#include <Kernel/Thread.h>
#include <Kernel/VM/MemoryManager.h>
@@ -58,6 +59,8 @@ static Descriptor s_idt[256];
static GenericInterruptHandler* s_interrupt_handler[GENERIC_INTERRUPT_HANDLERS_COUNT];
+static EntropySource s_entropy_source_interrupts{EntropySource::Static::Interrupts};
+
// The compiler can't see the calls to these functions inside assembly.
// Declare them, to avoid dead code warnings.
extern "C" void enter_thread_context(Thread* from_thread, Thread* to_thread);
@@ -709,6 +712,7 @@ void handle_interrupt(TrapFrame* trap)
auto& regs = *trap->regs;
ASSERT(regs.isr_number >= IRQ_VECTOR_BASE && regs.isr_number <= (IRQ_VECTOR_BASE + GENERIC_INTERRUPT_HANDLERS_COUNT));
u8 irq = (u8)(regs.isr_number - 0x50);
+ s_entropy_source_interrupts.add_random_event(irq);
auto* handler = s_interrupt_handler[irq];
ASSERT(handler);
handler->increment_invoking_counter();