mirror of
https://github.com/yuzu-mirror/yuzu.git
synced 2024-09-07 16:19:08 +01:00
kernel/thread: Fix potential crashes introduced in 26de4bb521
This amends cases where crashes can occur that were missed due to the odd way the previous code was set up (using 3DS memory regions that don't exist).
This commit is contained in:
parent
40e63ede6d
commit
e93fa7f2cc
3 changed files with 36 additions and 11 deletions
|
@ -28,20 +28,32 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> 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<std::vector<u8>>(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;
|
||||
|
|
|
@ -339,6 +339,17 @@ ResultVal<SharedPtr<Thread>> 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
|
||||
|
|
|
@ -265,6 +265,8 @@ public:
|
|||
private:
|
||||
Thread();
|
||||
~Thread() override;
|
||||
|
||||
std::shared_ptr<std::vector<u8>> tls_memory = std::make_shared<std::vector<u8>>();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue