mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2024-11-23 18:19:21 +01:00
kernel: Fix memory mapping issue introduced in https://github.com/citra-emu/citra/pull/6680 (#7208)
This commit is contained in:
parent
670e9936a4
commit
dc8425a986
@ -300,14 +300,15 @@ ResultCode Process::HeapFree(VAddr target, u32 size) {
|
|||||||
|
|
||||||
// Free heaps block by block
|
// Free heaps block by block
|
||||||
CASCADE_RESULT(auto backing_blocks, vm_manager.GetBackingBlocksForRange(target, size));
|
CASCADE_RESULT(auto backing_blocks, vm_manager.GetBackingBlocksForRange(target, size));
|
||||||
for (const auto& backing_block : backing_blocks) {
|
for (const auto& [backing_memory, block_size] : backing_blocks) {
|
||||||
memory_region->Free(backing_block.lower(), backing_block.upper() - backing_block.lower());
|
const auto backing_offset = kernel.memory.GetFCRAMOffset(backing_memory.GetPtr());
|
||||||
|
memory_region->Free(backing_offset, block_size);
|
||||||
|
holding_memory -= MemoryRegionInfo::Interval(backing_offset, backing_offset + block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode result = vm_manager.UnmapRange(target, size);
|
ResultCode result = vm_manager.UnmapRange(target, size);
|
||||||
ASSERT(result.IsSuccess());
|
ASSERT(result.IsSuccess());
|
||||||
|
|
||||||
holding_memory -= backing_blocks;
|
|
||||||
memory_used -= size;
|
memory_used -= size;
|
||||||
resource_limit->current_commit -= size;
|
resource_limit->current_commit -= size;
|
||||||
|
|
||||||
@ -504,9 +505,7 @@ ResultCode Process::Map(VAddr target, VAddr source, u32 size, VMAPermission perm
|
|||||||
|
|
||||||
CASCADE_RESULT(auto backing_blocks, vm_manager.GetBackingBlocksForRange(source, size));
|
CASCADE_RESULT(auto backing_blocks, vm_manager.GetBackingBlocksForRange(source, size));
|
||||||
VAddr interval_target = target;
|
VAddr interval_target = target;
|
||||||
for (const auto& backing_block : backing_blocks) {
|
for (const auto& [backing_memory, block_size] : backing_blocks) {
|
||||||
auto backing_memory = kernel.memory.GetFCRAMRef(backing_block.lower());
|
|
||||||
auto block_size = backing_block.upper() - backing_block.lower();
|
|
||||||
auto target_vma =
|
auto target_vma =
|
||||||
vm_manager.MapBackingMemory(interval_target, backing_memory, block_size, target_state);
|
vm_manager.MapBackingMemory(interval_target, backing_memory, block_size, target_state);
|
||||||
ASSERT(target_vma.Succeeded());
|
ASSERT(target_vma.Succeeded());
|
||||||
|
@ -70,10 +70,7 @@ ResultVal<std::shared_ptr<SharedMemory>> KernelSystem::CreateSharedMemory(
|
|||||||
|
|
||||||
auto backing_blocks = vm_manager.GetBackingBlocksForRange(address, size);
|
auto backing_blocks = vm_manager.GetBackingBlocksForRange(address, size);
|
||||||
ASSERT(backing_blocks.Succeeded()); // should success after verifying memory state above
|
ASSERT(backing_blocks.Succeeded()); // should success after verifying memory state above
|
||||||
for (const auto& interval : backing_blocks.Unwrap()) {
|
shared_memory->backing_blocks = std::move(backing_blocks).Unwrap();
|
||||||
shared_memory->backing_blocks.emplace_back(memory.GetFCRAMRef(interval.lower()),
|
|
||||||
interval.upper() - interval.lower());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_memory->base_address = address;
|
shared_memory->base_address = address;
|
||||||
|
@ -391,9 +391,9 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
|
|||||||
plgldr->OnMemoryChanged(process, Core::System::GetInstance().Kernel());
|
plgldr->OnMemoryChanged(process, Core::System::GetInstance().Kernel());
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<MemoryRegionInfo::IntervalSet> VMManager::GetBackingBlocksForRange(VAddr address,
|
ResultVal<std::vector<std::pair<MemoryRef, u32>>> VMManager::GetBackingBlocksForRange(VAddr address,
|
||||||
u32 size) {
|
u32 size) {
|
||||||
MemoryRegionInfo::IntervalSet backing_blocks;
|
std::vector<std::pair<MemoryRef, u32>> backing_blocks;
|
||||||
VAddr interval_target = address;
|
VAddr interval_target = address;
|
||||||
while (interval_target != address + size) {
|
while (interval_target != address + size) {
|
||||||
auto vma = FindVMA(interval_target);
|
auto vma = FindVMA(interval_target);
|
||||||
@ -404,10 +404,8 @@ ResultVal<MemoryRegionInfo::IntervalSet> VMManager::GetBackingBlocksForRange(VAd
|
|||||||
|
|
||||||
VAddr interval_end = std::min(address + size, vma->second.base + vma->second.size);
|
VAddr interval_end = std::min(address + size, vma->second.base + vma->second.size);
|
||||||
u32 interval_size = interval_end - interval_target;
|
u32 interval_size = interval_end - interval_target;
|
||||||
auto backing_memory = memory.GetFCRAMOffset(vma->second.backing_memory +
|
auto backing_memory = vma->second.backing_memory + (interval_target - vma->second.base);
|
||||||
(interval_target - vma->second.base));
|
backing_blocks.push_back({backing_memory, interval_size});
|
||||||
backing_blocks +=
|
|
||||||
MemoryRegionInfo::Interval(backing_memory, backing_memory + interval_size);
|
|
||||||
|
|
||||||
interval_target += interval_size;
|
interval_target += interval_size;
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,8 @@ public:
|
|||||||
void LogLayout(Common::Log::Level log_level) const;
|
void LogLayout(Common::Log::Level log_level) const;
|
||||||
|
|
||||||
/// Gets a list of backing memory blocks for the specified range
|
/// Gets a list of backing memory blocks for the specified range
|
||||||
ResultVal<MemoryRegionInfo::IntervalSet> GetBackingBlocksForRange(VAddr address, u32 size);
|
ResultVal<std::vector<std::pair<MemoryRef, u32>>> GetBackingBlocksForRange(VAddr address,
|
||||||
|
u32 size);
|
||||||
|
|
||||||
/// Each VMManager has its own page table, which is set as the main one when the owning process
|
/// Each VMManager has its own page table, which is set as the main one when the owning process
|
||||||
/// is scheduled.
|
/// is scheduled.
|
||||||
|
Loading…
Reference in New Issue
Block a user