diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 02d5a7a36..d45daca35 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp | |||
| @@ -55,22 +55,19 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u | |||
| 55 | Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); | 55 | Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); |
| 56 | } | 56 | } |
| 57 | } else { | 57 | } else { |
| 58 | // TODO(Subv): What happens if an application tries to create multiple memory blocks | ||
| 59 | // pointing to the same address? | ||
| 60 | auto& vm_manager = shared_memory->owner_process->vm_manager; | 58 | auto& vm_manager = shared_memory->owner_process->vm_manager; |
| 61 | // The memory is already available and mapped in the owner process. | 59 | // The memory is already available and mapped in the owner process. |
| 62 | auto vma = vm_manager.FindVMA(address)->second; | 60 | auto vma = vm_manager.FindVMA(address); |
| 63 | // Copy it over to our own storage | 61 | ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); |
| 64 | shared_memory->backing_block = std::make_shared<std::vector<u8>>( | 62 | ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); |
| 65 | vma.backing_block->data() + vma.offset, vma.backing_block->data() + vma.offset + size); | 63 | |
| 66 | shared_memory->backing_block_offset = 0; | 64 | // The returned VMA might be a bigger one encompassing the desired address. |
| 67 | // Unmap the existing pages | 65 | auto vma_offset = address - vma->first; |
| 68 | vm_manager.UnmapRange(address, size); | 66 | ASSERT_MSG(vma_offset + size <= vma->second.size, |
| 69 | // Map our own block into the address space | 67 | "Shared memory exceeds bounds of mapped block"); |
| 70 | vm_manager.MapMemoryBlock(address, shared_memory->backing_block, 0, size, | 68 | |
| 71 | MemoryState::Shared); | 69 | shared_memory->backing_block = vma->second.backing_block; |
| 72 | // Reprotect the block with the new permissions | 70 | shared_memory->backing_block_offset = vma->second.offset + vma_offset; |
| 73 | vm_manager.ReprotectRange(address, size, ConvertPermissions(permissions)); | ||
| 74 | } | 71 | } |
| 75 | 72 | ||
| 76 | shared_memory->base_address = address; | 73 | shared_memory->base_address = address; |
| @@ -184,4 +181,4 @@ u8* SharedMemory::GetPointer(u32 offset) { | |||
| 184 | return backing_block->data() + backing_block_offset + offset; | 181 | return backing_block->data() + backing_block_offset + offset; |
| 185 | } | 182 | } |
| 186 | 183 | ||
| 187 | } // namespace | 184 | } // namespace Kernel |