From 99eccf581e29e3a324242eb36af58f442737ba2d Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 23 Dec 2022 13:40:30 -0500 Subject: kernel: workaround static shared memory initialization --- src/core/hle/kernel/k_shared_memory.cpp | 69 +++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 25 deletions(-) (limited to 'src/core/hle/kernel/k_shared_memory.cpp') diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp index 10cd4c43d..0aa68103c 100644 --- a/src/core/hle/kernel/k_shared_memory.cpp +++ b/src/core/hle/kernel/k_shared_memory.cpp @@ -6,6 +6,7 @@ #include "core/hle/kernel/k_page_table.h" #include "core/hle/kernel/k_scoped_resource_reservation.h" #include "core/hle/kernel/k_shared_memory.h" +#include "core/hle/kernel/k_system_resource.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/svc_results.h" @@ -18,19 +19,19 @@ KSharedMemory::~KSharedMemory() { } Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, - KPageGroup&& page_list_, Svc::MemoryPermission owner_permission_, - Svc::MemoryPermission user_permission_, PAddr physical_address_, - std::size_t size_, std::string name_) { + Svc::MemoryPermission owner_permission_, + Svc::MemoryPermission user_permission_, std::size_t size_, + std::string name_) { // Set members. owner_process = owner_process_; device_memory = &device_memory_; - page_list = std::move(page_list_); owner_permission = owner_permission_; user_permission = user_permission_; - physical_address = physical_address_; - size = size_; + size = Common::AlignUp(size_, PageSize); name = std::move(name_); + const size_t num_pages = Common::DivideUp(size, PageSize); + // Get the resource limit. KResourceLimit* reslimit = kernel.GetSystemResourceLimit(); @@ -39,6 +40,17 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o size_); R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); + // Allocate the memory. + + //! HACK: Open continuous mapping from sysmodule pool. + auto option = KMemoryManager::EncodeOption(KMemoryManager::Pool::Secure, + KMemoryManager::Direction::FromBack); + physical_address = kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, option); + R_UNLESS(physical_address != 0, ResultOutOfMemory); + + //! Insert the result into our page group. + page_group.emplace(physical_address, num_pages); + // Commit our reservation. memory_reservation.Commit(); @@ -50,12 +62,23 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o is_initialized = true; // Clear all pages in the memory. - std::memset(device_memory_.GetPointer(physical_address_), 0, size_); + for (const auto& block : page_group->Nodes()) { + std::memset(device_memory_.GetPointer(block.GetAddress()), 0, block.GetSize()); + } return ResultSuccess; } void KSharedMemory::Finalize() { + // Close and finalize the page group. + // page_group->Close(); + // page_group->Finalize(); + + //! HACK: Manually close. + for (const auto& block : page_group->Nodes()) { + kernel.MemoryManager().Close(block.GetAddress(), block.GetNumPages()); + } + // Release the memory reservation. resource_limit->Release(LimitableResource::PhysicalMemoryMax, size); resource_limit->Close(); @@ -65,32 +88,28 @@ void KSharedMemory::Finalize() { } Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t map_size, - Svc::MemoryPermission permissions) { - const u64 page_count{(map_size + PageSize - 1) / PageSize}; - - if (page_list.GetNumPages() != page_count) { - UNIMPLEMENTED_MSG("Page count does not match"); - } + Svc::MemoryPermission map_perm) { + // Validate the size. + R_UNLESS(size == map_size, ResultInvalidSize); - const Svc::MemoryPermission expected = + // Validate the permission. + const Svc::MemoryPermission test_perm = &target_process == owner_process ? owner_permission : user_permission; - - if (permissions != expected) { - UNIMPLEMENTED_MSG("Permission does not match"); + if (test_perm == Svc::MemoryPermission::DontCare) { + ASSERT(map_perm == Svc::MemoryPermission::Read || map_perm == Svc::MemoryPermission::Write); + } else { + R_UNLESS(map_perm == test_perm, ResultInvalidNewMemoryPermission); } - return target_process.PageTable().MapPages(address, page_list, KMemoryState::Shared, - ConvertToKMemoryPermission(permissions)); + return target_process.PageTable().MapPages(address, *page_group, KMemoryState::Shared, + ConvertToKMemoryPermission(map_perm)); } Result KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) { - const u64 page_count{(unmap_size + PageSize - 1) / PageSize}; - - if (page_list.GetNumPages() != page_count) { - UNIMPLEMENTED_MSG("Page count does not match"); - } + // Validate the size. + R_UNLESS(size == unmap_size, ResultInvalidSize); - return target_process.PageTable().UnmapPages(address, page_list, KMemoryState::Shared); + return target_process.PageTable().UnmapPages(address, *page_group, KMemoryState::Shared); } } // namespace Kernel -- cgit v1.2.3