summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2024-01-31 14:31:13 +0100
committerGravatar Fernando Sahmkow2024-01-31 16:38:51 +0100
commitd57165df450e8a2fa811706758fb8ab352f623ae (patch)
treeeb8292e721409121f372e868d37ccb0426e90b42
parentDeviceMemory: Make counter types configurable (diff)
downloadyuzu-d57165df450e8a2fa811706758fb8ab352f623ae.tar.gz
yuzu-d57165df450e8a2fa811706758fb8ab352f623ae.tar.xz
yuzu-d57165df450e8a2fa811706758fb8ab352f623ae.zip
Device Memory Manager: ensure raster protection only within mapped device addresses.
Diffstat (limited to '')
-rw-r--r--src/core/device_memory_manager.inc40
1 files changed, 23 insertions, 17 deletions
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc
index 7afe54949..b026f4220 100644
--- a/src/core/device_memory_manager.inc
+++ b/src/core/device_memory_manager.inc
@@ -519,18 +519,32 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
519 const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE); 519 const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE);
520 size_t page = addr >> Memory::YUZU_PAGEBITS; 520 size_t page = addr >> Memory::YUZU_PAGEBITS;
521 auto [asid, base_vaddress] = ExtractCPUBacking(page); 521 auto [asid, base_vaddress] = ExtractCPUBacking(page);
522 size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS;
523 auto* memory_device_inter = registered_processes[asid.id]; 522 auto* memory_device_inter = registered_processes[asid.id];
523 const auto release_pending = [&] {
524 if (uncache_bytes > 0) {
525 MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
526 uncache_bytes, false);
527 uncache_bytes = 0;
528 }
529 if (cache_bytes > 0) {
530 MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS,
531 cache_bytes, true);
532 cache_bytes = 0;
533 }
534 };
524 for (; page != page_end; ++page) { 535 for (; page != page_end; ++page) {
525 CounterAtomicType& count = cached_pages->at(page >> subentries_shift).Count(page); 536 CounterAtomicType& count = cached_pages->at(page >> subentries_shift).Count(page);
537 auto [asid_2, vpage] = ExtractCPUBacking(page);
538 vpage >>= Memory::YUZU_PAGEBITS;
526 539
527 if (delta > 0) { 540 if (vpage == 0) [[unlikely]] {
528 ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<CounterType>::max(), 541 release_pending();
529 "Count may overflow!"); 542 continue;
530 } else if (delta < 0) { 543 }
531 ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!"); 544
532 } else { 545 if (asid.id != asid_2.id) [[unlikely]] {
533 ASSERT_MSG(false, "Delta must be non-zero!"); 546 release_pending();
547 memory_device_inter = registered_processes[asid_2.id];
534 } 548 }
535 549
536 // Adds or subtracts 1, as count is a unsigned 8-bit value 550 // Adds or subtracts 1, as count is a unsigned 8-bit value
@@ -557,16 +571,8 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
557 cache_bytes, true); 571 cache_bytes, true);
558 cache_bytes = 0; 572 cache_bytes = 0;
559 } 573 }
560 vpage++;
561 }
562 if (uncache_bytes > 0) {
563 MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
564 uncache_bytes, false);
565 }
566 if (cache_bytes > 0) {
567 MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
568 true);
569 } 574 }
575 release_pending();
570} 576}
571 577
572} // namespace Core 578} // namespace Core