1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-12-23 02:42:09 +00:00

kern: simplify global rng initialization

This commit is contained in:
Michael Scire 2021-04-07 12:42:35 -07:00 committed by SciresM
parent 0f8b7be2d2
commit 8e4be9aef9
2 changed files with 30 additions and 14 deletions

View file

@ -42,8 +42,8 @@ namespace ams::kern::board::nintendo::nx {
/* Nintendo uses std::mt19937_t for randomness. */ /* Nintendo uses std::mt19937_t for randomness. */
/* To save space (and because mt19337_t isn't secure anyway), */ /* To save space (and because mt19337_t isn't secure anyway), */
/* We will use TinyMT. */ /* We will use TinyMT. */
bool g_initialized_random_generator; constinit bool g_initialized_random_generator;
util::TinyMT g_random_generator; constinit util::TinyMT g_random_generator;
constinit KSpinLock g_random_lock; constinit KSpinLock g_random_lock;
ALWAYS_INLINE size_t GetRealMemorySizeForInit() { ALWAYS_INLINE size_t GetRealMemorySizeForInit() {
@ -90,13 +90,10 @@ namespace ams::kern::board::nintendo::nx {
return value; return value;
} }
void EnsureRandomGeneratorInitialized() { ALWAYS_INLINE u64 GenerateRandomU64FromSmc() {
if (AMS_UNLIKELY(!g_initialized_random_generator)) { u64 value;
u64 seed; smc::GenerateRandomBytes(std::addressof(value), sizeof(value));
smc::GenerateRandomBytes(&seed, sizeof(seed)); return value;
g_random_generator.Initialize(reinterpret_cast<u32*>(&seed), sizeof(seed) / sizeof(u32));
g_initialized_random_generator = true;
}
} }
ALWAYS_INLINE u64 GenerateRandomU64FromGenerator() { ALWAYS_INLINE u64 GenerateRandomU64FromGenerator() {
@ -439,6 +436,14 @@ namespace ams::kern::board::nintendo::nx {
/* System Initialization. */ /* System Initialization. */
void KSystemControl::InitializePhase1() { void KSystemControl::InitializePhase1() {
/* Initialize our random generator. */
{
u64 seed;
smc::GenerateRandomBytes(std::addressof(seed), sizeof(seed));
g_random_generator.Initialize(reinterpret_cast<u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
g_initialized_random_generator = true;
}
/* Set IsDebugMode. */ /* Set IsDebugMode. */
{ {
KTargetSystem::SetIsDebugMode(GetConfigBool(smc::ConfigItem::IsDebugMode)); KTargetSystem::SetIsDebugMode(GetConfigBool(smc::ConfigItem::IsDebugMode));
@ -544,18 +549,23 @@ namespace ams::kern::board::nintendo::nx {
KScopedInterruptDisable intr_disable; KScopedInterruptDisable intr_disable;
KScopedSpinLock lk(g_random_lock); KScopedSpinLock lk(g_random_lock);
EnsureRandomGeneratorInitialized();
return GenerateUniformRange(min, max, GenerateRandomU64FromGenerator); if (AMS_LIKELY(g_initialized_random_generator)) {
return GenerateUniformRange(min, max, GenerateRandomU64FromGenerator);
} else {
return GenerateUniformRange(min, max, GenerateRandomU64FromSmc);
}
} }
u64 KSystemControl::GenerateRandomU64() { u64 KSystemControl::GenerateRandomU64() {
KScopedInterruptDisable intr_disable; KScopedInterruptDisable intr_disable;
KScopedSpinLock lk(g_random_lock); KScopedSpinLock lk(g_random_lock);
EnsureRandomGeneratorInitialized(); if (AMS_LIKELY(g_initialized_random_generator)) {
return GenerateRandomU64FromGenerator();
return GenerateRandomU64FromGenerator(); } else {
return GenerateRandomU64FromSmc();
}
} }
void KSystemControl::SleepSystem() { void KSystemControl::SleepSystem() {

View file

@ -49,6 +49,9 @@ namespace ams::kern {
/* Initialize the carveout and the system resource limit. */ /* Initialize the carveout and the system resource limit. */
KSystemControl::InitializePhase1(); KSystemControl::InitializePhase1();
/* Synchronize all cores before proceeding, to ensure access to the global rng is consistent. */
cpu::SynchronizeAllCores();
/* Initialize the memory manager and the KPageBuffer slabheap. */ /* Initialize the memory manager and the KPageBuffer slabheap. */
{ {
const auto &management_region = KMemoryLayout::GetPoolManagementRegion(); const auto &management_region = KMemoryLayout::GetPoolManagementRegion();
@ -74,6 +77,9 @@ namespace ams::kern {
Kernel::InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize()); Kernel::InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize());
} }
} else {
/* Synchronize all cores before proceeding, to ensure access to the global rng is consistent. */
cpu::SynchronizeAllCores();
} }
/* Initialize the supervisor page table for each core. */ /* Initialize the supervisor page table for each core. */