diff options
| author | 2017-12-28 21:35:49 -0500 | |
|---|---|---|
| committer | 2017-12-28 21:35:49 -0500 | |
| commit | 3421e1617e0b64ca0b1be18d4fefe769d35244d0 (patch) | |
| tree | 9999fc9c439a7dd066ba5f062af097906a088aad /src/core/hle/kernel/process.cpp | |
| parent | svc: Implement SetHeapSize. (diff) | |
| download | yuzu-3421e1617e0b64ca0b1be18d4fefe769d35244d0.tar.gz yuzu-3421e1617e0b64ca0b1be18d4fefe769d35244d0.tar.xz yuzu-3421e1617e0b64ca0b1be18d4fefe769d35244d0.zip | |
process: Add method to mirror a memory region.
Diffstat (limited to 'src/core/hle/kernel/process.cpp')
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
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) { | |||
| 267 | return RESULT_SUCCESS; | 267 | return RESULT_SUCCESS; |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | ResultCode Process::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size) { | ||
| 271 | auto vma = vm_manager.FindVMA(src_addr); | ||
| 272 | |||
| 273 | ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); | ||
| 274 | ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); | ||
| 275 | |||
| 276 | // The returned VMA might be a bigger one encompassing the desired address. | ||
| 277 | auto vma_offset = src_addr - vma->first; | ||
| 278 | ASSERT_MSG(vma_offset + size <= vma->second.size, | ||
| 279 | "Shared memory exceeds bounds of mapped block"); | ||
| 280 | |||
| 281 | const std::shared_ptr<std::vector<u8>>& backing_block = vma->second.backing_block; | ||
| 282 | size_t backing_block_offset = vma->second.offset + vma_offset; | ||
| 283 | |||
| 284 | CASCADE_RESULT(auto new_vma, | ||
| 285 | vm_manager.MapMemoryBlock(dst_addr, backing_block, backing_block_offset, size, | ||
| 286 | vma->second.meminfo_state)); | ||
| 287 | // Protect mirror with permissions from old region | ||
| 288 | vm_manager.Reprotect(new_vma, vma->second.permissions); | ||
| 289 | // Remove permissions from old region | ||
| 290 | vm_manager.Reprotect(vma, VMAPermission::None); | ||
| 291 | |||
| 292 | return RESULT_SUCCESS; | ||
| 293 | } | ||
| 294 | |||
| 270 | Kernel::Process::Process() {} | 295 | Kernel::Process::Process() {} |
| 271 | Kernel::Process::~Process() {} | 296 | Kernel::Process::~Process() {} |
| 272 | 297 | ||