forked from eden-emu/eden
		
	Merge pull request #8178 from tech-ticks/skyline-icache-fix
hle: kernel: Invalidate entire icache in UnmapProcessMemory and UnmapCodeMemory (fixes #8174)
This commit is contained in:
		
						commit
						4d4a17ef6f
					
				
					 4 changed files with 34 additions and 15 deletions
				
			
		|  | @ -346,7 +346,8 @@ ResultCode KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, std:: | ||||||
|     return ResultSuccess; |     return ResultSuccess; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultCode KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size) { | ResultCode KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size, | ||||||
|  |                                        ICacheInvalidationStrategy icache_invalidation_strategy) { | ||||||
|     // Validate the mapping request.
 |     // Validate the mapping request.
 | ||||||
|     R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode), |     R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode), | ||||||
|              ResultInvalidMemoryRegion); |              ResultInvalidMemoryRegion); | ||||||
|  | @ -396,7 +397,11 @@ ResultCode KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std | ||||||
|     bool reprotected_pages = false; |     bool reprotected_pages = false; | ||||||
|     SCOPE_EXIT({ |     SCOPE_EXIT({ | ||||||
|         if (reprotected_pages && any_code_pages) { |         if (reprotected_pages && any_code_pages) { | ||||||
|  |             if (icache_invalidation_strategy == ICacheInvalidationStrategy::InvalidateRange) { | ||||||
|                 system.InvalidateCpuInstructionCacheRange(dst_address, size); |                 system.InvalidateCpuInstructionCacheRange(dst_address, size); | ||||||
|  |             } else { | ||||||
|  |                 system.InvalidateCpuInstructionCaches(); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  | @ -563,6 +568,8 @@ ResultCode KPageTable::UnmapProcessMemory(VAddr dst_addr, std::size_t size, | ||||||
|     block_manager->Update(dst_addr, num_pages, KMemoryState::Free, KMemoryPermission::None, |     block_manager->Update(dst_addr, num_pages, KMemoryState::Free, KMemoryPermission::None, | ||||||
|                           KMemoryAttribute::None); |                           KMemoryAttribute::None); | ||||||
| 
 | 
 | ||||||
|  |     system.InvalidateCpuInstructionCaches(); | ||||||
|  | 
 | ||||||
|     return ResultSuccess; |     return ResultSuccess; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -26,6 +26,8 @@ class KMemoryBlockManager; | ||||||
| 
 | 
 | ||||||
| class KPageTable final { | class KPageTable final { | ||||||
| public: | public: | ||||||
|  |     enum class ICacheInvalidationStrategy : u32 { InvalidateRange, InvalidateAll }; | ||||||
|  | 
 | ||||||
|     YUZU_NON_COPYABLE(KPageTable); |     YUZU_NON_COPYABLE(KPageTable); | ||||||
|     YUZU_NON_MOVEABLE(KPageTable); |     YUZU_NON_MOVEABLE(KPageTable); | ||||||
| 
 | 
 | ||||||
|  | @ -38,7 +40,8 @@ public: | ||||||
|     ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state, |     ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state, | ||||||
|                               KMemoryPermission perm); |                               KMemoryPermission perm); | ||||||
|     ResultCode MapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size); |     ResultCode MapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size); | ||||||
|     ResultCode UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size); |     ResultCode UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size, | ||||||
|  |                                ICacheInvalidationStrategy icache_invalidation_strategy); | ||||||
|     ResultCode UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table, |     ResultCode UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table, | ||||||
|                                   VAddr src_addr); |                                   VAddr src_addr); | ||||||
|     ResultCode MapPhysicalMemory(VAddr addr, std::size_t size); |     ResultCode MapPhysicalMemory(VAddr addr, std::size_t size); | ||||||
|  |  | ||||||
|  | @ -1713,7 +1713,8 @@ static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_ha | ||||||
|         return ResultInvalidMemoryRegion; |         return ResultInvalidMemoryRegion; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return page_table.UnmapCodeMemory(dst_address, src_address, size); |     return page_table.UnmapCodeMemory(dst_address, src_address, size, | ||||||
|  |                                       KPageTable::ICacheInvalidationStrategy::InvalidateAll); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Exits the current process
 | /// Exits the current process
 | ||||||
|  |  | ||||||
|  | @ -389,8 +389,12 @@ public: | ||||||
| 
 | 
 | ||||||
|             if (bss_size) { |             if (bss_size) { | ||||||
|                 auto block_guard = detail::ScopeExit([&] { |                 auto block_guard = detail::ScopeExit([&] { | ||||||
|                     page_table.UnmapCodeMemory(addr + nro_size, bss_addr, bss_size); |                     page_table.UnmapCodeMemory( | ||||||
|                     page_table.UnmapCodeMemory(addr, nro_addr, nro_size); |                         addr + nro_size, bss_addr, bss_size, | ||||||
|  |                         Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange); | ||||||
|  |                     page_table.UnmapCodeMemory( | ||||||
|  |                         addr, nro_addr, nro_size, | ||||||
|  |                         Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange); | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|                 const ResultCode result{ |                 const ResultCode result{ | ||||||
|  | @ -570,17 +574,21 @@ public: | ||||||
|         auto& page_table{system.CurrentProcess()->PageTable()}; |         auto& page_table{system.CurrentProcess()->PageTable()}; | ||||||
| 
 | 
 | ||||||
|         if (info.bss_size != 0) { |         if (info.bss_size != 0) { | ||||||
|             CASCADE_CODE(page_table.UnmapCodeMemory(info.nro_address + info.text_size + |             CASCADE_CODE(page_table.UnmapCodeMemory( | ||||||
|                                                         info.ro_size + info.data_size, |                 info.nro_address + info.text_size + info.ro_size + info.data_size, info.bss_address, | ||||||
|                                                     info.bss_address, info.bss_size)); |                 info.bss_size, Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange)); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         CASCADE_CODE(page_table.UnmapCodeMemory(info.nro_address + info.text_size + info.ro_size, |         CASCADE_CODE(page_table.UnmapCodeMemory( | ||||||
|                                                 info.src_addr + info.text_size + info.ro_size, |             info.nro_address + info.text_size + info.ro_size, | ||||||
|                                                 info.data_size)); |             info.src_addr + info.text_size + info.ro_size, info.data_size, | ||||||
|         CASCADE_CODE(page_table.UnmapCodeMemory(info.nro_address + info.text_size, |             Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange)); | ||||||
|                                                 info.src_addr + info.text_size, info.ro_size)); |         CASCADE_CODE(page_table.UnmapCodeMemory( | ||||||
|         CASCADE_CODE(page_table.UnmapCodeMemory(info.nro_address, info.src_addr, info.text_size)); |             info.nro_address + info.text_size, info.src_addr + info.text_size, info.ro_size, | ||||||
|  |             Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange)); | ||||||
|  |         CASCADE_CODE(page_table.UnmapCodeMemory( | ||||||
|  |             info.nro_address, info.src_addr, info.text_size, | ||||||
|  |             Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange)); | ||||||
|         return ResultSuccess; |         return ResultSuccess; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei