kern: randomize dynamic slab heaps to reflect 10.x changes

This commit is contained in:
Michael Scire 2020-04-19 00:35:05 -07:00
parent b4d003b4b9
commit dcfb3bc9b5
4 changed files with 45 additions and 20 deletions

View file

@ -64,11 +64,12 @@ namespace ams::kern {
this->page_bitmap.Initialize(metadata_ptr, this->count);
/* Free the pages to the bitmap. */
PageBuffer *cur_page = GetPointer<PageBuffer>(this->address);
std::memset(GetPointer<PageBuffer>(this->address), 0, this->count * sizeof(PageBuffer));
for (size_t i = 0; i < this->count; i++) {
std::memset(cur_page, 0, sizeof(*cur_page));
this->page_bitmap.SetBit(i);
}
return ResultSuccess();
}
constexpr KVirtualAddress GetAddress() const { return this->address; }

View file

@ -77,6 +77,23 @@ namespace ams::kern {
this->size = this->page_allocator->GetSize();
}
void Initialize(KDynamicPageManager *page_allocator, size_t num_objects) {
MESOSPHERE_ASSERT(page_allocator != nullptr);
/* Initialize members. */
this->Initialize(page_allocator);
/* Allocate until we have the correct number of objects. */
while (this->count < num_objects) {
auto *allocated = reinterpret_cast<T *>(this->page_allocator->Allocate());
MESOSPHERE_ABORT_UNLESS(allocated != nullptr);
for (size_t i = 0; i < sizeof(PageBuffer) / sizeof(T); i++) {
this->GetImpl()->Free(allocated + i);
}
this->count += sizeof(PageBuffer) / sizeof(T);
}
}
T *Allocate() {
T *allocated = reinterpret_cast<T *>(this->GetImpl()->Allocate());

View file

@ -57,13 +57,13 @@ namespace ams::kern {
return std::addressof(this->ref_counts[(addr - this->GetAddress()) / PageSize]);
}
public:
void Initialize(KDynamicPageManager *next_allocator, RefCount *rc) {
BaseHeap::Initialize(next_allocator);
void Initialize(KDynamicPageManager *page_allocator, RefCount *rc) {
BaseHeap::Initialize(page_allocator);
this->Initialize(rc);
}
void Initialize(KVirtualAddress memory, size_t sz, RefCount *rc) {
BaseHeap::Initialize(memory, sz);
void Initialize(KDynamicPageManager *page_allocator, size_t object_count, RefCount *rc) {
BaseHeap::Initialize(page_allocator, object_count);
this->Initialize(rc);
}

View file

@ -19,6 +19,8 @@ namespace ams::kern {
namespace {
KDynamicPageManager g_resource_manager_page_manager;
template<typename T>
ALWAYS_INLINE void PrintMemoryRegion(const char *prefix, const T &extents) {
static_assert(std::is_same<decltype(extents.GetAddress()), uintptr_t>::value);
@ -88,24 +90,29 @@ namespace ams::kern {
void Kernel::InitializeResourceManagers(KVirtualAddress address, size_t size) {
/* Ensure that the buffer is suitable for our use. */
const size_t app_size = ApplicationMemoryBlockSlabHeapSize * sizeof(KMemoryBlock);
const size_t sys_size = SystemMemoryBlockSlabHeapSize * sizeof(KMemoryBlock);
const size_t info_size = BlockInfoSlabHeapSize * sizeof(KBlockInfo);
const size_t fixed_size = util::AlignUp(app_size + sys_size + info_size, PageSize);
//const size_t app_size = ApplicationMemoryBlockSlabHeapSize * sizeof(KMemoryBlock);
//const size_t sys_size = SystemMemoryBlockSlabHeapSize * sizeof(KMemoryBlock);
//const size_t info_size = BlockInfoSlabHeapSize * sizeof(KBlockInfo);
//const size_t fixed_size = util::AlignUp(app_size + sys_size + info_size, PageSize);
MESOSPHERE_ABORT_UNLESS(util::IsAligned(GetInteger(address), PageSize));
MESOSPHERE_ABORT_UNLESS(util::IsAligned(size, PageSize));
MESOSPHERE_ABORT_UNLESS(fixed_size < size);
size_t pt_size = size - fixed_size;
const size_t rc_size = util::AlignUp(KPageTableManager::CalculateReferenceCountSize(pt_size), PageSize);
MESOSPHERE_ABORT_UNLESS(rc_size < pt_size);
pt_size -= rc_size;
/* Ensure that we have space for our reference counts. */
const size_t rc_size = util::AlignUp(KPageTableManager::CalculateReferenceCountSize(size), PageSize);
MESOSPHERE_ABORT_UNLESS(rc_size < size);
size -= rc_size;
/* Initialize the slabheaps. */
s_app_memory_block_manager.Initialize(address + pt_size, app_size);
s_sys_memory_block_manager.Initialize(address + pt_size + app_size, sys_size);
s_block_info_manager.Initialize(address + pt_size + app_size + sys_size, info_size);
s_page_table_manager.Initialize(address, pt_size, GetPointer<KPageTableManager::RefCount>(address + pt_size + fixed_size));
/* Initialize the resource managers' shared page manager. */
g_resource_manager_page_manager.Initialize(address, size);
/* Initialize the fixed-size slabheaps. */
s_app_memory_block_manager.Initialize(std::addressof(g_resource_manager_page_manager), ApplicationMemoryBlockSlabHeapSize);
s_sys_memory_block_manager.Initialize(std::addressof(g_resource_manager_page_manager), SystemMemoryBlockSlabHeapSize);
s_block_info_manager.Initialize(std::addressof(g_resource_manager_page_manager), BlockInfoSlabHeapSize);
/* Reserve all remaining pages for the page table manager. */
const size_t num_pt_pages = g_resource_manager_page_manager.GetCount() - g_resource_manager_page_manager.GetUsed();
s_page_table_manager.Initialize(std::addressof(g_resource_manager_page_manager), num_pt_pages, GetPointer<KPageTableManager::RefCount>(address + size));
}
void Kernel::PrintLayout() {