1
0
Fork 0
forked from suyu/suyu

Device Memory Manager: ensure raster protection only within mapped device addresses.

This commit is contained in:
Fernando Sahmkow 2024-01-31 14:31:13 +01:00
parent 738e9a79a0
commit d57165df45

View file

@ -519,18 +519,32 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE); const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE);
size_t page = addr >> Memory::YUZU_PAGEBITS; size_t page = addr >> Memory::YUZU_PAGEBITS;
auto [asid, base_vaddress] = ExtractCPUBacking(page); auto [asid, base_vaddress] = ExtractCPUBacking(page);
size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS;
auto* memory_device_inter = registered_processes[asid.id]; auto* memory_device_inter = registered_processes[asid.id];
const auto release_pending = [&] {
if (uncache_bytes > 0) {
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
uncache_bytes, false);
uncache_bytes = 0;
}
if (cache_bytes > 0) {
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS,
cache_bytes, true);
cache_bytes = 0;
}
};
for (; page != page_end; ++page) { for (; page != page_end; ++page) {
CounterAtomicType& count = cached_pages->at(page >> subentries_shift).Count(page); CounterAtomicType& count = cached_pages->at(page >> subentries_shift).Count(page);
auto [asid_2, vpage] = ExtractCPUBacking(page);
vpage >>= Memory::YUZU_PAGEBITS;
if (delta > 0) { if (vpage == 0) [[unlikely]] {
ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<CounterType>::max(), release_pending();
"Count may overflow!"); continue;
} else if (delta < 0) { }
ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!");
} else { if (asid.id != asid_2.id) [[unlikely]] {
ASSERT_MSG(false, "Delta must be non-zero!"); release_pending();
memory_device_inter = registered_processes[asid_2.id];
} }
// Adds or subtracts 1, as count is a unsigned 8-bit value // 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
cache_bytes, true); cache_bytes, true);
cache_bytes = 0; cache_bytes = 0;
} }
vpage++;
}
if (uncache_bytes > 0) {
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
uncache_bytes, false);
}
if (cache_bytes > 0) {
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
true);
} }
release_pending();
} }
} // namespace Core } // namespace Core