diff options
| author | 2018-08-04 01:19:01 -0400 | |
|---|---|---|
| committer | 2018-08-04 01:19:01 -0400 | |
| commit | d43dad001e8afa866eddc3d15bb5a6f47d797583 (patch) | |
| tree | 8732faeb184c2ce4a3b0b37bfd051dee136ff759 | |
| parent | Merge pull request #910 from lioncash/unused (diff) | |
| parent | kernel/thread: Fix potential crashes introduced in 26de4bb521b1ace7af76eff4f6... (diff) | |
| download | yuzu-d43dad001e8afa866eddc3d15bb5a6f47d797583.tar.gz yuzu-d43dad001e8afa866eddc3d15bb5a6f47d797583.tar.xz yuzu-d43dad001e8afa866eddc3d15bb5a6f47d797583.zip | |
Merge pull request #917 from lioncash/crash
kernel/thread: Fix potential crashes introduced in 26de4bb5
| -rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 38 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 11 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 2 |
3 files changed, 38 insertions, 13 deletions
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index b3ddebb3d..21ddc2f7d 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp | |||
| @@ -28,20 +28,32 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u | |||
| 28 | shared_memory->permissions = permissions; | 28 | shared_memory->permissions = permissions; |
| 29 | shared_memory->other_permissions = other_permissions; | 29 | shared_memory->other_permissions = other_permissions; |
| 30 | 30 | ||
| 31 | auto& vm_manager = shared_memory->owner_process->vm_manager; | 31 | if (address == 0) { |
| 32 | 32 | shared_memory->backing_block = std::make_shared<std::vector<u8>>(size); | |
| 33 | // The memory is already available and mapped in the owner process. | 33 | shared_memory->backing_block_offset = 0; |
| 34 | auto vma = vm_manager.FindVMA(address); | 34 | |
| 35 | ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); | 35 | // Refresh the address mappings for the current process. |
| 36 | ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); | 36 | if (Core::CurrentProcess() != nullptr) { |
| 37 | 37 | Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings( | |
| 38 | // The returned VMA might be a bigger one encompassing the desired address. | 38 | shared_memory->backing_block.get()); |
| 39 | auto vma_offset = address - vma->first; | 39 | } |
| 40 | ASSERT_MSG(vma_offset + size <= vma->second.size, | 40 | } else { |
| 41 | "Shared memory exceeds bounds of mapped block"); | 41 | auto& vm_manager = shared_memory->owner_process->vm_manager; |
| 42 | |||
| 43 | // The memory is already available and mapped in the owner process. | ||
| 44 | auto vma = vm_manager.FindVMA(address); | ||
| 45 | ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); | ||
| 46 | ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); | ||
| 47 | |||
| 48 | // The returned VMA might be a bigger one encompassing the desired address. | ||
| 49 | auto vma_offset = address - vma->first; | ||
| 50 | ASSERT_MSG(vma_offset + size <= vma->second.size, | ||
| 51 | "Shared memory exceeds bounds of mapped block"); | ||
| 52 | |||
| 53 | shared_memory->backing_block = vma->second.backing_block; | ||
| 54 | shared_memory->backing_block_offset = vma->second.offset + vma_offset; | ||
| 55 | } | ||
| 42 | 56 | ||
| 43 | shared_memory->backing_block = vma->second.backing_block; | ||
| 44 | shared_memory->backing_block_offset = vma->second.offset + vma_offset; | ||
| 45 | shared_memory->base_address = address; | 57 | shared_memory->base_address = address; |
| 46 | 58 | ||
| 47 | return shared_memory; | 59 | return shared_memory; |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index ea9554cbb..b9022feae 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -339,6 +339,17 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 339 | tls_slots.emplace_back(0); // The page is completely available at the start | 339 | tls_slots.emplace_back(0); // The page is completely available at the start |
| 340 | available_page = tls_slots.size() - 1; | 340 | available_page = tls_slots.size() - 1; |
| 341 | available_slot = 0; // Use the first slot in the new page | 341 | available_slot = 0; // Use the first slot in the new page |
| 342 | |||
| 343 | // Allocate some memory from the end of the linear heap for this region. | ||
| 344 | const size_t offset = thread->tls_memory->size(); | ||
| 345 | thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0); | ||
| 346 | |||
| 347 | auto& vm_manager = owner_process->vm_manager; | ||
| 348 | vm_manager.RefreshMemoryBlockMappings(thread->tls_memory.get()); | ||
| 349 | |||
| 350 | vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, | ||
| 351 | thread->tls_memory, 0, Memory::PAGE_SIZE, | ||
| 352 | MemoryState::ThreadLocal); | ||
| 342 | } | 353 | } |
| 343 | 354 | ||
| 344 | // Mark the slot as used | 355 | // Mark the slot as used |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 146955e13..adc804248 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -265,6 +265,8 @@ public: | |||
| 265 | private: | 265 | private: |
| 266 | Thread(); | 266 | Thread(); |
| 267 | ~Thread() override; | 267 | ~Thread() override; |
| 268 | |||
| 269 | std::shared_ptr<std::vector<u8>> tls_memory = std::make_shared<std::vector<u8>>(); | ||
| 268 | }; | 270 | }; |
| 269 | 271 | ||
| 270 | /** | 272 | /** |