| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #include "core/core.h"
- #include "core/hle/kernel/k_scoped_resource_reservation.h"
- #include "core/hle/kernel/k_system_resource.h"
- namespace Kernel {
- Result KSecureSystemResource::Initialize(size_t size, KResourceLimit* resource_limit,
- KMemoryManager::Pool pool) {
- // Set members.
- m_resource_limit = resource_limit;
- m_resource_size = size;
- m_resource_pool = pool;
- // Determine required size for our secure resource.
- const size_t secure_size = this->CalculateRequiredSecureMemorySize();
- // Reserve memory for our secure resource.
- KScopedResourceReservation memory_reservation(
- m_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, secure_size);
- R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
- // Allocate secure memory.
- R_TRY(KSystemControl::AllocateSecureMemory(m_kernel, std::addressof(m_resource_address),
- m_resource_size, static_cast<u32>(m_resource_pool)));
- ASSERT(m_resource_address != 0);
- // Ensure we clean up the secure memory, if we fail past this point.
- ON_RESULT_FAILURE {
- KSystemControl::FreeSecureMemory(m_kernel, m_resource_address, m_resource_size,
- static_cast<u32>(m_resource_pool));
- };
- // Check that our allocation is bigger than the reference counts needed for it.
- const size_t rc_size =
- Common::AlignUp(KPageTableSlabHeap::CalculateReferenceCountSize(m_resource_size), PageSize);
- R_UNLESS(m_resource_size > rc_size, ResultOutOfMemory);
- // Get resource pointer.
- KPhysicalAddress resource_paddr =
- KPageTable::GetHeapPhysicalAddress(m_kernel, m_resource_address);
- auto* resource =
- m_kernel.System().DeviceMemory().GetPointer<KPageTableManager::RefCount>(resource_paddr);
- // Initialize slab heaps.
- m_dynamic_page_manager.Initialize(m_resource_address + rc_size, m_resource_size - rc_size,
- PageSize);
- m_page_table_heap.Initialize(std::addressof(m_dynamic_page_manager), 0, resource);
- m_memory_block_heap.Initialize(std::addressof(m_dynamic_page_manager), 0);
- m_block_info_heap.Initialize(std::addressof(m_dynamic_page_manager), 0);
- // Initialize managers.
- m_page_table_manager.Initialize(std::addressof(m_dynamic_page_manager),
- std::addressof(m_page_table_heap));
- m_memory_block_slab_manager.Initialize(std::addressof(m_dynamic_page_manager),
- std::addressof(m_memory_block_heap));
- m_block_info_manager.Initialize(std::addressof(m_dynamic_page_manager),
- std::addressof(m_block_info_heap));
- // Set our managers.
- this->SetManagers(m_memory_block_slab_manager, m_block_info_manager, m_page_table_manager);
- // Commit the memory reservation.
- memory_reservation.Commit();
- // Open reference to our resource limit.
- m_resource_limit->Open();
- // Set ourselves as initialized.
- m_is_initialized = true;
- R_SUCCEED();
- }
- void KSecureSystemResource::Finalize() {
- // Check that we have no outstanding allocations.
- ASSERT(m_memory_block_slab_manager.GetUsed() == 0);
- ASSERT(m_block_info_manager.GetUsed() == 0);
- ASSERT(m_page_table_manager.GetUsed() == 0);
- // Free our secure memory.
- KSystemControl::FreeSecureMemory(m_kernel, m_resource_address, m_resource_size,
- static_cast<u32>(m_resource_pool));
- // Release the memory reservation.
- m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax,
- this->CalculateRequiredSecureMemorySize());
- // Close reference to our resource limit.
- m_resource_limit->Close();
- }
- size_t KSecureSystemResource::CalculateRequiredSecureMemorySize(size_t size,
- KMemoryManager::Pool pool) {
- return KSystemControl::CalculateRequiredSecureMemorySize(size, static_cast<u32>(pool));
- }
- } // namespace Kernel
|