summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorkonrad <konrad@serenityos.org>2023-01-08 05:30:40 +0100
committerJelle Raaijmakers <jelle@gmta.nl>2023-01-25 23:17:36 +0100
commite1c50b83e1de39785eb30a695f805d2029d77148 (patch)
treeecb96cc14ccfb89634a471a998c1397f2af87128 /Kernel
parent7c8e61f4d149c8404d3c2432b7244482ec346ec4 (diff)
downloadserenity-e1c50b83e1de39785eb30a695f805d2029d77148.zip
Kernel: Use RDSEED assembly snippet to seed RNG on Aarch64
There’s similar RDRAND register (encoded as ‘s3_3_c2_c4_0ʼ) to be added if needed. RNG CPU feature on Aarch64 guarantees existence of both RDSEED and RDRAND registers simultaneously—in contrast to x86-64, where respective instructions are independent of each other.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Arch/aarch64/ASM_wrapper.h13
-rw-r--r--Kernel/Arch/aarch64/Processor.cpp2
-rw-r--r--Kernel/Random.cpp11
3 files changed, 26 insertions, 0 deletions
diff --git a/Kernel/Arch/aarch64/ASM_wrapper.h b/Kernel/Arch/aarch64/ASM_wrapper.h
index 7710cbb695..963d257229 100644
--- a/Kernel/Arch/aarch64/ASM_wrapper.h
+++ b/Kernel/Arch/aarch64/ASM_wrapper.h
@@ -91,6 +91,19 @@ inline void enter_el1_from_el2()
: "x0");
}
+inline u64 read_rndrrs()
+{
+ u64 value = 0;
+
+ asm volatile(
+ "retry:\n"
+ "mrs %[value], s3_3_c2_c4_1 \n" // encoded RNDRRS register
+ "b.eq retry\n"
+ : [value] "=r"(value));
+
+ return value;
+}
+
}
namespace Kernel {
diff --git a/Kernel/Arch/aarch64/Processor.cpp b/Kernel/Arch/aarch64/Processor.cpp
index 418894800a..81e29fafc5 100644
--- a/Kernel/Arch/aarch64/Processor.cpp
+++ b/Kernel/Arch/aarch64/Processor.cpp
@@ -44,6 +44,8 @@ void Processor::initialize()
dmesgln("CPU[{}]: Supports {}", m_cpu, build_cpu_feature_names(m_features));
dmesgln("CPU[{}]: Physical address bit width: {}", m_cpu, m_physical_address_bit_width);
dmesgln("CPU[{}]: Virtual address bit width: {}", m_cpu, m_virtual_address_bit_width);
+ if (!has_feature(CPUFeature::RNG))
+ dmesgln("CPU[{}]: {} not detected, randomness will be poor", m_cpu, cpu_feature_to_description(CPUFeature::RNG));
}
[[noreturn]] void Processor::halt()
diff --git a/Kernel/Random.cpp b/Kernel/Random.cpp
index a98b9ab0cc..96f176540f 100644
--- a/Kernel/Random.cpp
+++ b/Kernel/Random.cpp
@@ -10,6 +10,8 @@
#if ARCH(X86_64)
# include <Kernel/Arch/x86_64/Time/HPET.h>
# include <Kernel/Arch/x86_64/Time/RTC.h>
+#elif ARCH(AARCH64)
+# include <Kernel/Arch/aarch64/ASM_wrapper.h>
#endif
#include <Kernel/Devices/RandomDevice.h>
#include <Kernel/Random.h>
@@ -59,6 +61,15 @@ UNMAP_AFTER_INIT KernelRng::KernelRng()
current_time += 0x40b2u;
}
}
+#elif ARCH(AARCH64)
+ if (Processor::current().has_feature(CPUFeature::RNG)) {
+ dmesgln("KernelRng: Using RNDRRS as entropy source");
+ for (size_t i = 0; i < pool_count * reseed_threshold; ++i) {
+ add_random_event(Aarch64::Asm::read_rndrrs(), i % 32);
+ }
+ } else {
+ dmesgln("KernelRng: No entropy source available!");
+ }
#else
dmesgln("KernelRng: No entropy source available!");
#endif