From cfa9a322c723619c60e12d4630044ee79fea5718 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Sat, 10 Nov 2018 11:14:29 -0500 Subject: [PATCH] Kernel/SharedMemory: set and reset source memory state --- src/core/hle/kernel/kernel.h | 12 ++++++------ src/core/hle/kernel/shared_memory.cpp | 21 ++++++++++++++------- src/core/hle/kernel/svc.cpp | 7 ++++--- src/core/hle/service/apt/apt.cpp | 9 +++++---- src/core/hle/service/csnd/csnd_snd.cpp | 8 +++++--- src/core/hle/service/gsp/gsp_gpu.cpp | 8 +++++--- src/core/hle/service/hid/hid.cpp | 8 +++++--- src/core/hle/service/ir/ir_rst.cpp | 8 +++++--- 8 files changed, 49 insertions(+), 32 deletions(-) diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index a6db1eb39..cf6e95fe4 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -170,12 +170,12 @@ public: * linear heap. * @param name Optional object name, used for debugging purposes. */ - SharedPtr CreateSharedMemory(Process* owner_process, u32 size, - MemoryPermission permissions, - MemoryPermission other_permissions, - VAddr address = 0, - MemoryRegion region = MemoryRegion::BASE, - std::string name = "Unknown"); + ResultVal> CreateSharedMemory(Process* owner_process, u32 size, + MemoryPermission permissions, + MemoryPermission other_permissions, + VAddr address = 0, + MemoryRegion region = MemoryRegion::BASE, + std::string name = "Unknown"); /** * Creates a shared memory object from a block of memory managed by an HLE applet. diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index f32651d49..eec74bfde 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -17,13 +17,16 @@ SharedMemory::~SharedMemory() { kernel.GetMemoryRegion(MemoryRegion::SYSTEM) ->Free(interval.lower(), interval.upper() - interval.lower()); } + if (base_address != 0 && owner_process != nullptr) { + owner_process->vm_manager.ChangeMemoryState(base_address, size, MemoryState::Locked, + VMAPermission::None, MemoryState::Private, + VMAPermission::ReadWrite); + } } -SharedPtr KernelSystem::CreateSharedMemory(Process* owner_process, u32 size, - MemoryPermission permissions, - MemoryPermission other_permissions, - VAddr address, MemoryRegion region, - std::string name) { +ResultVal> KernelSystem::CreateSharedMemory( + Process* owner_process, u32 size, MemoryPermission permissions, + MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) { SharedPtr shared_memory(new SharedMemory(*this)); shared_memory->owner_process = owner_process; @@ -53,13 +56,17 @@ SharedPtr KernelSystem::CreateSharedMemory(Process* owner_process, auto& vm_manager = shared_memory->owner_process->vm_manager; // The memory is already available and mapped in the owner process. + CASCADE_CODE(vm_manager.ChangeMemoryState(address, size, MemoryState::Private, + VMAPermission::ReadWrite, MemoryState::Locked, + SharedMemory::ConvertPermissions(permissions))); + auto backing_blocks = vm_manager.GetBackingBlocksForRange(address, size); - ASSERT_MSG(backing_blocks.Succeeded(), "Trying to share freed memory"); + ASSERT(backing_blocks.Succeeded()); // should success after verifying memory state above shared_memory->backing_blocks = std::move(backing_blocks).Unwrap(); } shared_memory->base_address = address; - return shared_memory; + return MakeResult(shared_memory); } SharedPtr KernelSystem::CreateSharedMemoryForApplet( diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 53728a66d..ab341a6bf 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1250,9 +1250,10 @@ ResultCode SVC::CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my if (addr == 0 && current_process->flags.shared_device_mem) region = current_process->flags.memory_region; - shared_memory = kernel.CreateSharedMemory( - current_process.get(), size, static_cast(my_permission), - static_cast(other_permission), addr, region); + CASCADE_RESULT(shared_memory, + kernel.CreateSharedMemory( + current_process.get(), size, static_cast(my_permission), + static_cast(other_permission), addr, region)); CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(shared_memory))); LOG_WARNING(Kernel_SVC, "called addr=0x{:08X}", addr); diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 44b81a0fd..db8247a2a 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -861,10 +861,11 @@ Module::Module(Core::System& system) : system(system) { applet_manager = std::make_shared(system); using Kernel::MemoryPermission; - shared_font_mem = - system.Kernel().CreateSharedMemory(nullptr, 0x332000, // 3272 KB - MemoryPermission::ReadWrite, MemoryPermission::Read, 0, - Kernel::MemoryRegion::SYSTEM, "APT:SharedFont"); + shared_font_mem = system.Kernel() + .CreateSharedMemory(nullptr, 0x332000, // 3272 KB + MemoryPermission::ReadWrite, MemoryPermission::Read, + 0, Kernel::MemoryRegion::SYSTEM, "APT:SharedFont") + .Unwrap(); lock = system.Kernel().CreateMutex(false, "APT_U:Lock"); } diff --git a/src/core/hle/service/csnd/csnd_snd.cpp b/src/core/hle/service/csnd/csnd_snd.cpp index ec4f55c0d..432a405c6 100644 --- a/src/core/hle/service/csnd/csnd_snd.cpp +++ b/src/core/hle/service/csnd/csnd_snd.cpp @@ -20,9 +20,11 @@ void CSND_SND::Initialize(Kernel::HLERequestContext& ctx) { using Kernel::MemoryPermission; mutex = system.Kernel().CreateMutex(false, "CSND:mutex"); - shared_memory = system.Kernel().CreateSharedMemory( - nullptr, size, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 0, - Kernel::MemoryRegion::BASE, "CSND:SharedMemory"); + shared_memory = system.Kernel() + .CreateSharedMemory(nullptr, size, MemoryPermission::ReadWrite, + MemoryPermission::ReadWrite, 0, + Kernel::MemoryRegion::BASE, "CSND:SharedMemory") + .Unwrap(); IPC::RequestBuilder rb = rp.MakeBuilder(1, 3); rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/gsp/gsp_gpu.cpp b/src/core/hle/service/gsp/gsp_gpu.cpp index 8ed79ebca..6e6d0e585 100644 --- a/src/core/hle/service/gsp/gsp_gpu.cpp +++ b/src/core/hle/service/gsp/gsp_gpu.cpp @@ -787,9 +787,11 @@ GSP_GPU::GSP_GPU(Core::System& system) : ServiceFramework("gsp::Gpu", 2), system RegisterHandlers(functions); using Kernel::MemoryPermission; - shared_memory = system.Kernel().CreateSharedMemory( - nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 0, - Kernel::MemoryRegion::BASE, "GSP:SharedMemory"); + shared_memory = system.Kernel() + .CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, + MemoryPermission::ReadWrite, 0, + Kernel::MemoryRegion::BASE, "GSP:SharedMemory") + .Unwrap(); first_initialization = true; }; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 805cc6c91..e42b265df 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -361,9 +361,11 @@ std::shared_ptr Module::Interface::GetModule() const { Module::Module(Core::System& system) : system(system) { using namespace Kernel; - shared_mem = system.Kernel().CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, - MemoryPermission::Read, 0, MemoryRegion::BASE, - "HID:SharedMemory"); + shared_mem = + system.Kernel() + .CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, + MemoryPermission::Read, 0, MemoryRegion::BASE, "HID:SharedMemory") + .Unwrap(); // Create event handles event_pad_or_touch_1 = system.Kernel().CreateEvent(ResetType::OneShot, "HID:EventPadOrTouch1"); diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index 33e4fc0ff..7b7849afd 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -149,9 +149,11 @@ IR_RST::IR_RST(Core::System& system) : ServiceFramework("ir:rst", 1), system(sys using namespace Kernel; // Note: these two kernel objects are even available before Initialize service function is // called. - shared_memory = system.Kernel().CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, - MemoryPermission::Read, 0, - MemoryRegion::BASE, "IRRST:SharedMemory"); + shared_memory = + system.Kernel() + .CreateSharedMemory(nullptr, 0x1000, MemoryPermission::ReadWrite, + MemoryPermission::Read, 0, MemoryRegion::BASE, "IRRST:SharedMemory") + .Unwrap(); update_event = system.Kernel().CreateEvent(ResetType::OneShot, "IRRST:UpdateEvent"); update_callback_id = system.CoreTiming().RegisterEvent(