mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00: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
					
				
					 4 changed files with 13 additions and 18 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue