From 3421e1617e0b64ca0b1be18d4fefe769d35244d0 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 28 Dec 2017 21:35:49 -0500 Subject: process: Add method to mirror a memory region. --- src/core/hle/kernel/process.cpp | 25 +++++++++++++++++++++++++ src/core/hle/kernel/process.h | 2 ++ 2 files changed, 27 insertions(+) (limited to 'src/core') diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 98c5b0905..9bcb08fc9 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -267,6 +267,31 @@ ResultCode Process::LinearFree(VAddr target, u32 size) { return RESULT_SUCCESS; } +ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) { + auto vma = vm_manager.FindVMA(src_addr); + + ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); + ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); + + // The returned VMA might be a bigger one encompassing the desired address. + auto vma_offset = src_addr - vma->first; + ASSERT_MSG(vma_offset + size <= vma->second.size, + "Shared memory exceeds bounds of mapped block"); + + const std::shared_ptr>& backing_block = vma->second.backing_block; + size_t backing_block_offset = vma->second.offset + vma_offset; + + CASCADE_RESULT(auto new_vma, + vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size, + vma->second.meminfo_state)); + // Protect mirror with permissions from old region + vm_manager.Reprotect(new_vma, vma->second.permissions); + // Remove permissions from old region + vm_manager.Reprotect(vma, VMAPermission::None); + + return RESULT_SUCCESS; +} + Kernel::Process::Process() {} Kernel::Process::~Process() {} diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index f05f2703e..3b646c076 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -177,6 +177,8 @@ public: ResultVal LinearAllocate(VAddr target, u32 size, VMAPermission perms); ResultCode LinearFree(VAddr target, u32 size); + ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size); + private: Process(); ~Process() override; -- cgit v1.2.3