summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/k_page_table.cpp11
-rw-r--r--src/core/hle/kernel/k_page_table.h5
-rw-r--r--src/core/hle/kernel/svc.cpp3
-rw-r--r--src/core/hle/service/ldr/ldr.cpp30
4 files changed, 34 insertions, 15 deletions
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index 599013cf6..47ea3c89c 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -346,7 +346,8 @@ ResultCode KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, std::
346 return ResultSuccess; 346 return ResultSuccess;
347} 347}
348 348
349ResultCode KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size) { 349ResultCode KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size,
350 ICacheInvalidationStrategy icache_invalidation_strategy) {
350 // Validate the mapping request. 351 // Validate the mapping request.
351 R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode), 352 R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode),
352 ResultInvalidMemoryRegion); 353 ResultInvalidMemoryRegion);
@@ -396,7 +397,11 @@ ResultCode KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std
396 bool reprotected_pages = false; 397 bool reprotected_pages = false;
397 SCOPE_EXIT({ 398 SCOPE_EXIT({
398 if (reprotected_pages && any_code_pages) { 399 if (reprotected_pages && any_code_pages) {
399 system.InvalidateCpuInstructionCacheRange(dst_address, size); 400 if (icache_invalidation_strategy == ICacheInvalidationStrategy::InvalidateRange) {
401 system.InvalidateCpuInstructionCacheRange(dst_address, size);
402 } else {
403 system.InvalidateCpuInstructionCaches();
404 }
400 } 405 }
401 }); 406 });
402 407
@@ -563,6 +568,8 @@ ResultCode KPageTable::UnmapProcessMemory(VAddr dst_addr, std::size_t size,
563 block_manager->Update(dst_addr, num_pages, KMemoryState::Free, KMemoryPermission::None, 568 block_manager->Update(dst_addr, num_pages, KMemoryState::Free, KMemoryPermission::None,
564 KMemoryAttribute::None); 569 KMemoryAttribute::None);
565 570
571 system.InvalidateCpuInstructionCaches();
572
566 return ResultSuccess; 573 return ResultSuccess;
567} 574}
568 575
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index bfabdf38c..dd6022975 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -26,6 +26,8 @@ class KMemoryBlockManager;
26 26
27class KPageTable final { 27class KPageTable final {
28public: 28public:
29 enum class ICacheInvalidationStrategy : u32 { InvalidateRange, InvalidateAll };
30
29 YUZU_NON_COPYABLE(KPageTable); 31 YUZU_NON_COPYABLE(KPageTable);
30 YUZU_NON_MOVEABLE(KPageTable); 32 YUZU_NON_MOVEABLE(KPageTable);
31 33
@@ -38,7 +40,8 @@ public:
38 ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state, 40 ResultCode MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state,
39 KMemoryPermission perm); 41 KMemoryPermission perm);
40 ResultCode MapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size); 42 ResultCode MapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size);
41 ResultCode UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size); 43 ResultCode UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size,
44 ICacheInvalidationStrategy icache_invalidation_strategy);
42 ResultCode UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table, 45 ResultCode UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table,
43 VAddr src_addr); 46 VAddr src_addr);
44 ResultCode MapPhysicalMemory(VAddr addr, std::size_t size); 47 ResultCode MapPhysicalMemory(VAddr addr, std::size_t size);
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 976d63234..0c86435b5 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1713,7 +1713,8 @@ static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_ha
1713 return ResultInvalidMemoryRegion; 1713 return ResultInvalidMemoryRegion;
1714 } 1714 }
1715 1715
1716 return page_table.UnmapCodeMemory(dst_address, src_address, size); 1716 return page_table.UnmapCodeMemory(dst_address, src_address, size,
1717 KPageTable::ICacheInvalidationStrategy::InvalidateAll);
1717} 1718}
1718 1719
1719/// Exits the current process 1720/// Exits the current process
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 2477c5612..cf727c167 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -389,8 +389,12 @@ public:
389 389
390 if (bss_size) { 390 if (bss_size) {
391 auto block_guard = detail::ScopeExit([&] { 391 auto block_guard = detail::ScopeExit([&] {
392 page_table.UnmapCodeMemory(addr + nro_size, bss_addr, bss_size); 392 page_table.UnmapCodeMemory(
393 page_table.UnmapCodeMemory(addr, nro_addr, nro_size); 393 addr + nro_size, bss_addr, bss_size,
394 Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange);
395 page_table.UnmapCodeMemory(
396 addr, nro_addr, nro_size,
397 Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange);
394 }); 398 });
395 399
396 const ResultCode result{ 400 const ResultCode result{
@@ -570,17 +574,21 @@ public:
570 auto& page_table{system.CurrentProcess()->PageTable()}; 574 auto& page_table{system.CurrentProcess()->PageTable()};
571 575
572 if (info.bss_size != 0) { 576 if (info.bss_size != 0) {
573 CASCADE_CODE(page_table.UnmapCodeMemory(info.nro_address + info.text_size + 577 CASCADE_CODE(page_table.UnmapCodeMemory(
574 info.ro_size + info.data_size, 578 info.nro_address + info.text_size + info.ro_size + info.data_size, info.bss_address,
575 info.bss_address, info.bss_size)); 579 info.bss_size, Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange));
576 } 580 }
577 581
578 CASCADE_CODE(page_table.UnmapCodeMemory(info.nro_address + info.text_size + info.ro_size, 582 CASCADE_CODE(page_table.UnmapCodeMemory(
579 info.src_addr + info.text_size + info.ro_size, 583 info.nro_address + info.text_size + info.ro_size,
580 info.data_size)); 584 info.src_addr + info.text_size + info.ro_size, info.data_size,
581 CASCADE_CODE(page_table.UnmapCodeMemory(info.nro_address + info.text_size, 585 Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange));
582 info.src_addr + info.text_size, info.ro_size)); 586 CASCADE_CODE(page_table.UnmapCodeMemory(
583 CASCADE_CODE(page_table.UnmapCodeMemory(info.nro_address, info.src_addr, info.text_size)); 587 info.nro_address + info.text_size, info.src_addr + info.text_size, info.ro_size,
588 Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange));
589 CASCADE_CODE(page_table.UnmapCodeMemory(
590 info.nro_address, info.src_addr, info.text_size,
591 Kernel::KPageTable::ICacheInvalidationStrategy::InvalidateRange));
584 return ResultSuccess; 592 return ResultSuccess;
585 } 593 }
586 594