kern: Update page bitmaps/alloc to reflect 10.0.0 changes
This commit is contained in:
@@ -765,6 +765,7 @@ namespace ams::kern::arch::arm64 {
|
||||
KVirtualAddress l3_table = util::AlignDown(reinterpret_cast<uintptr_t>(l3_entry), PageSize);
|
||||
if (this->GetPageTableManager().IsInPageTableHeap(l3_table)) {
|
||||
this->GetPageTableManager().Close(l3_table, L2BlockSize / L3BlockSize);
|
||||
ClearPageTable(l3_table);
|
||||
this->FreePageTable(page_list, l3_table);
|
||||
}
|
||||
}
|
||||
@@ -816,6 +817,7 @@ namespace ams::kern::arch::arm64 {
|
||||
KVirtualAddress l2_table = util::AlignDown(reinterpret_cast<uintptr_t>(l2_entry), PageSize);
|
||||
if (this->GetPageTableManager().IsInPageTableHeap(l2_table)) {
|
||||
this->GetPageTableManager().Close(l2_table, L1BlockSize / L2BlockSize);
|
||||
ClearPageTable(l2_table);
|
||||
this->FreePageTable(page_list, l2_table);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,15 @@ namespace ams::kern::board::nintendo::nx {
|
||||
return value;
|
||||
}
|
||||
|
||||
void EnsureRandomGeneratorInitialized() {
|
||||
if (AMS_UNLIKELY(!g_initialized_random_generator)) {
|
||||
u64 seed;
|
||||
smc::GenerateRandomBytes(&seed, sizeof(seed));
|
||||
g_random_generator.Initialize(reinterpret_cast<u32*>(&seed), sizeof(seed) / sizeof(u32));
|
||||
g_initialized_random_generator = true;
|
||||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE u64 GenerateRandomU64FromGenerator() {
|
||||
return g_random_generator.GenerateRandomU64();
|
||||
}
|
||||
@@ -304,16 +313,20 @@ namespace ams::kern::board::nintendo::nx {
|
||||
KScopedInterruptDisable intr_disable;
|
||||
KScopedSpinLock lk(g_random_lock);
|
||||
|
||||
if (AMS_UNLIKELY(!g_initialized_random_generator)) {
|
||||
u64 seed;
|
||||
GenerateRandomBytes(&seed, sizeof(seed));
|
||||
g_random_generator.Initialize(reinterpret_cast<u32*>(&seed), sizeof(seed) / sizeof(u32));
|
||||
g_initialized_random_generator = true;
|
||||
}
|
||||
EnsureRandomGeneratorInitialized();
|
||||
|
||||
return GenerateUniformRange(min, max, GenerateRandomU64FromGenerator);
|
||||
}
|
||||
|
||||
u64 KSystemControl::GenerateRandomU64() {
|
||||
KScopedInterruptDisable intr_disable;
|
||||
KScopedSpinLock lk(g_random_lock);
|
||||
|
||||
EnsureRandomGeneratorInitialized();
|
||||
|
||||
return GenerateRandomU64();
|
||||
}
|
||||
|
||||
void KSystemControl::SleepSystem() {
|
||||
MESOSPHERE_LOG("SleepSystem() was called\n");
|
||||
KSleepManager::SleepSystem();
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace ams::kern {
|
||||
Impl *chosen_manager = nullptr;
|
||||
KVirtualAddress allocated_block = Null<KVirtualAddress>;
|
||||
for (chosen_manager = this->GetFirstManager(pool, dir); chosen_manager != nullptr; chosen_manager = this->GetNextManager(chosen_manager, dir)) {
|
||||
allocated_block = chosen_manager->AllocateBlock(heap_index);
|
||||
allocated_block = chosen_manager->AllocateBlock(heap_index, true);
|
||||
if (allocated_block != Null<KVirtualAddress>) {
|
||||
break;
|
||||
}
|
||||
@@ -129,19 +129,7 @@ namespace ams::kern {
|
||||
return allocated_block;
|
||||
}
|
||||
|
||||
Result KMemoryManager::Allocate(KPageGroup *out, size_t num_pages, u32 option) {
|
||||
MESOSPHERE_ASSERT(out != nullptr);
|
||||
MESOSPHERE_ASSERT(out->GetNumPages() == 0);
|
||||
|
||||
/* Early return if we're allocating no pages. */
|
||||
if (num_pages == 0) {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
/* Lock the pool that we're allocating from. */
|
||||
const auto [pool, dir] = DecodeOption(option);
|
||||
KScopedLightLock lk(this->pool_locks[pool]);
|
||||
|
||||
Result KMemoryManager::AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool optimize, bool random) {
|
||||
/* Choose a heap based on our page size request. */
|
||||
const s32 heap_index = KPageHeap::GetBlockIndex(num_pages);
|
||||
R_UNLESS(0 <= heap_index, svc::ResultOutOfMemory());
|
||||
@@ -162,7 +150,7 @@ namespace ams::kern {
|
||||
for (Impl *cur_manager = this->GetFirstManager(pool, dir); cur_manager != nullptr; cur_manager = this->GetNextManager(cur_manager, dir)) {
|
||||
while (num_pages >= pages_per_alloc) {
|
||||
/* Allocate a block. */
|
||||
KVirtualAddress allocated_block = cur_manager->AllocateBlock(index);
|
||||
KVirtualAddress allocated_block = cur_manager->AllocateBlock(index, random);
|
||||
if (allocated_block == Null<KVirtualAddress>) {
|
||||
break;
|
||||
}
|
||||
@@ -175,7 +163,7 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
/* Maintain the optimized memory bitmap, if we should. */
|
||||
if (this->has_optimized_process[pool]) {
|
||||
if (optimize) {
|
||||
cur_manager->TrackAllocationForOptimizedProcess(allocated_block, pages_per_alloc);
|
||||
}
|
||||
|
||||
@@ -193,6 +181,21 @@ namespace ams::kern {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result KMemoryManager::Allocate(KPageGroup *out, size_t num_pages, u32 option) {
|
||||
MESOSPHERE_ASSERT(out != nullptr);
|
||||
MESOSPHERE_ASSERT(out->GetNumPages() == 0);
|
||||
|
||||
/* Early return if we're allocating no pages. */
|
||||
R_SUCCEED_IF(num_pages == 0);
|
||||
|
||||
/* Lock the pool that we're allocating from. */
|
||||
const auto [pool, dir] = DecodeOption(option);
|
||||
KScopedLightLock lk(this->pool_locks[pool]);
|
||||
|
||||
/* Allocate the page group. */
|
||||
return this->AllocatePageGroupImpl(out, num_pages, pool, dir, this->has_optimized_process[pool], true);
|
||||
}
|
||||
|
||||
size_t KMemoryManager::Impl::Initialize(const KMemoryRegion *region, Pool p, KVirtualAddress metadata, KVirtualAddress metadata_end) {
|
||||
/* Calculate metadata sizes. */
|
||||
const size_t ref_count_size = (region->GetSize() / PageSize) * sizeof(u16);
|
||||
|
||||
@@ -51,11 +51,11 @@ namespace ams::kern {
|
||||
return num_free;
|
||||
}
|
||||
|
||||
KVirtualAddress KPageHeap::AllocateBlock(s32 index) {
|
||||
KVirtualAddress KPageHeap::AllocateBlock(s32 index, bool random) {
|
||||
const size_t needed_size = this->blocks[index].GetSize();
|
||||
|
||||
for (s32 i = index; i < static_cast<s32>(this->num_blocks); i++) {
|
||||
if (const KVirtualAddress addr = this->blocks[i].PopBlock(); addr != Null<KVirtualAddress>) {
|
||||
if (const KVirtualAddress addr = this->blocks[i].PopBlock(random); addr != Null<KVirtualAddress>) {
|
||||
if (const size_t allocated_size = this->blocks[i].GetSize(); allocated_size > needed_size) {
|
||||
this->Free(addr + needed_size, (allocated_size - needed_size) / PageSize);
|
||||
}
|
||||
|
||||
@@ -20,35 +20,36 @@ namespace ams::kern {
|
||||
|
||||
Result KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) {
|
||||
/* Initialize our members. */
|
||||
this->address_space_width = (is_64_bit) ? BITSIZEOF(u64) : BITSIZEOF(u32);
|
||||
this->address_space_start = KProcessAddress(GetInteger(start));
|
||||
this->address_space_end = KProcessAddress(GetInteger(end));
|
||||
this->is_kernel = true;
|
||||
this->enable_aslr = true;
|
||||
this->address_space_width = (is_64_bit) ? BITSIZEOF(u64) : BITSIZEOF(u32);
|
||||
this->address_space_start = KProcessAddress(GetInteger(start));
|
||||
this->address_space_end = KProcessAddress(GetInteger(end));
|
||||
this->is_kernel = true;
|
||||
this->enable_aslr = true;
|
||||
|
||||
this->heap_region_start = 0;
|
||||
this->heap_region_end = 0;
|
||||
this->current_heap_end = 0;
|
||||
this->alias_region_start = 0;
|
||||
this->alias_region_end = 0;
|
||||
this->stack_region_start = 0;
|
||||
this->stack_region_end = 0;
|
||||
this->kernel_map_region_start = 0;
|
||||
this->kernel_map_region_end = 0;
|
||||
this->alias_code_region_start = 0;
|
||||
this->alias_code_region_end = 0;
|
||||
this->code_region_start = 0;
|
||||
this->code_region_end = 0;
|
||||
this->max_heap_size = 0;
|
||||
this->max_physical_memory_size = 0;
|
||||
this->heap_region_start = 0;
|
||||
this->heap_region_end = 0;
|
||||
this->current_heap_end = 0;
|
||||
this->alias_region_start = 0;
|
||||
this->alias_region_end = 0;
|
||||
this->stack_region_start = 0;
|
||||
this->stack_region_end = 0;
|
||||
this->kernel_map_region_start = 0;
|
||||
this->kernel_map_region_end = 0;
|
||||
this->alias_code_region_start = 0;
|
||||
this->alias_code_region_end = 0;
|
||||
this->code_region_start = 0;
|
||||
this->code_region_end = 0;
|
||||
this->max_heap_size = 0;
|
||||
this->max_physical_memory_size = 0;
|
||||
this->mapped_unsafe_physical_memory = 0;
|
||||
|
||||
this->memory_block_slab_manager = std::addressof(Kernel::GetSystemMemoryBlockManager());
|
||||
this->block_info_manager = std::addressof(Kernel::GetBlockInfoManager());
|
||||
this->memory_block_slab_manager = std::addressof(Kernel::GetSystemMemoryBlockManager());
|
||||
this->block_info_manager = std::addressof(Kernel::GetBlockInfoManager());
|
||||
|
||||
this->allocate_option = KMemoryManager::EncodeOption(KMemoryManager::Pool_System, KMemoryManager::Direction_FromFront);
|
||||
this->heap_fill_value = MemoryFillValue_Zero;
|
||||
this->ipc_fill_value = MemoryFillValue_Zero;
|
||||
this->stack_fill_value = MemoryFillValue_Zero;
|
||||
this->allocate_option = KMemoryManager::EncodeOption(KMemoryManager::Pool_System, KMemoryManager::Direction_FromFront);
|
||||
this->heap_fill_value = MemoryFillValue_Zero;
|
||||
this->ipc_fill_value = MemoryFillValue_Zero;
|
||||
this->stack_fill_value = MemoryFillValue_Zero;
|
||||
|
||||
this->cached_physical_linear_region = nullptr;
|
||||
this->cached_physical_heap_region = nullptr;
|
||||
@@ -222,9 +223,10 @@ namespace ams::kern {
|
||||
}
|
||||
|
||||
/* Set heap and fill members. */
|
||||
this->current_heap_end = this->heap_region_start;
|
||||
this->max_heap_size = 0;
|
||||
this->max_physical_memory_size = 0;
|
||||
this->current_heap_end = this->heap_region_start;
|
||||
this->max_heap_size = 0;
|
||||
this->max_physical_memory_size = 0;
|
||||
this->mapped_unsafe_physical_memory = 0;
|
||||
|
||||
const bool fill_memory = KTargetSystem::IsDebugMemoryFillEnabled();
|
||||
this->heap_fill_value = fill_memory ? MemoryFillValue_Heap : MemoryFillValue_Zero;
|
||||
|
||||
@@ -35,7 +35,8 @@ namespace ams::kern {
|
||||
|
||||
/* Create and clear the process local region. */
|
||||
R_TRY(this->CreateThreadLocalRegion(std::addressof(this->plr_address)));
|
||||
std::memset(this->GetThreadLocalRegionPointer(this->plr_address), 0, ams::svc::ThreadLocalRegionSize);
|
||||
this->plr_heap_address = this->GetThreadLocalRegionPointer(this->plr_address);
|
||||
std::memset(this->plr_heap_address, 0, ams::svc::ThreadLocalRegionSize);
|
||||
|
||||
/* Copy in the name from parameters. */
|
||||
static_assert(sizeof(params.name) < sizeof(this->name));
|
||||
|
||||
Reference in New Issue
Block a user