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::Create(SharedPtr owner_process, u shared_memory->permissions = permissions; shared_memory->other_permissions = other_permissions; - auto& vm_manager = shared_memory->owner_process->vm_manager; + if (address == 0) { + shared_memory->backing_block = std::make_shared>(size); + shared_memory->backing_block_offset = 0; - // The memory is already available and mapped in the owner process. - auto vma = vm_manager.FindVMA(address); - ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); - ASSERT_MSG(vma->second.backing_block, "Backing block doesn't exist for address"); + // Refresh the address mappings for the current process. + if (Core::CurrentProcess() != nullptr) { + Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings( + shared_memory->backing_block.get()); + } + } else { + auto& vm_manager = shared_memory->owner_process->vm_manager; - // The returned VMA might be a bigger one encompassing the desired address. - auto vma_offset = address - vma->first; - ASSERT_MSG(vma_offset + size <= vma->second.size, - "Shared memory exceeds bounds of mapped block"); + // The memory is already available and mapped in the owner process. + auto vma = vm_manager.FindVMA(address); + 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 = address - vma->first; + ASSERT_MSG(vma_offset + size <= vma->second.size, + "Shared memory exceeds bounds of mapped block"); + + shared_memory->backing_block = vma->second.backing_block; + shared_memory->backing_block_offset = vma->second.offset + vma_offset; + } - shared_memory->backing_block = vma->second.backing_block; - shared_memory->backing_block_offset = vma->second.offset + vma_offset; shared_memory->base_address = address; 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> Thread::Create(std::string name, VAddr entry_point, tls_slots.emplace_back(0); // The page is completely available at the start available_page = tls_slots.size() - 1; available_slot = 0; // Use the first slot in the new page + + // Allocate some memory from the end of the linear heap for this region. + const size_t offset = thread->tls_memory->size(); + thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0); + + auto& vm_manager = owner_process->vm_manager; + vm_manager.RefreshMemoryBlockMappings(thread->tls_memory.get()); + + vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, + thread->tls_memory, 0, Memory::PAGE_SIZE, + MemoryState::ThreadLocal); } // 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: private: Thread(); ~Thread() override; + + std::shared_ptr> tls_memory = std::make_shared>(); }; /**