From 4594c3b31014655fb0b37f1305598fc3cbafdc73 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Tue, 8 Dec 2020 00:42:17 +0000 Subject: [PATCH] Signal memory tracking before/after mapping into another process (#1785) * Signal memory tracking before/after mapping into another process * Wording. * Add missing method. --- Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs | 8 ++++++++ Ryujinx.Memory.Tests/MockVirtualMemoryManager.cs | 5 +++++ Ryujinx.Memory/AddressSpaceManager.cs | 5 +++++ Ryujinx.Memory/IVirtualMemoryManager.cs | 1 + 4 files changed, 19 insertions(+) diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs index 63ac8583e..05ad9f617 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs @@ -1656,6 +1656,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory } } + // Signal a read for any resources tracking reads in the region, as the other process is likely to use their data. + _cpuMemory.SignalMemoryTracking(addressTruncated, endAddrRounded - addressTruncated, false); + lock (_blocks) { KernelResult result; @@ -2036,6 +2039,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory ulong endAddr = address + size; ulong addressRounded = BitUtils.AlignUp (address, PageSize); + ulong addressTruncated = BitUtils.AlignDown(address, PageSize); + ulong endAddrRounded = BitUtils.AlignUp (endAddr, PageSize); ulong endAddrTruncated = BitUtils.AlignDown(endAddr, PageSize); ulong pagesCount = addressRounded < endAddrTruncated ? (endAddrTruncated - addressRounded) / PageSize : 0; @@ -2071,6 +2076,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory return KernelResult.OutOfResource; } + // Anything on the client side should see this memory as modified. + _cpuMemory.SignalMemoryTracking(addressTruncated, endAddrRounded - addressTruncated, true); + lock (_blocks) { foreach (KMemoryInfo info in IterateOverRange(addressRounded, endAddrTruncated)) diff --git a/Ryujinx.Memory.Tests/MockVirtualMemoryManager.cs b/Ryujinx.Memory.Tests/MockVirtualMemoryManager.cs index c673bc803..62b3ee4a1 100644 --- a/Ryujinx.Memory.Tests/MockVirtualMemoryManager.cs +++ b/Ryujinx.Memory.Tests/MockVirtualMemoryManager.cs @@ -75,6 +75,11 @@ namespace Ryujinx.Memory.Tests throw new NotImplementedException(); } + public void SignalMemoryTracking(ulong va, ulong size, bool write) + { + throw new NotImplementedException(); + } + public void TrackingReprotect(ulong va, ulong size, MemoryPermission protection) { } diff --git a/Ryujinx.Memory/AddressSpaceManager.cs b/Ryujinx.Memory/AddressSpaceManager.cs index c6d6cab56..50c7adad7 100644 --- a/Ryujinx.Memory/AddressSpaceManager.cs +++ b/Ryujinx.Memory/AddressSpaceManager.cs @@ -545,5 +545,10 @@ namespace Ryujinx.Memory _pageTable[l0] = null; } } + + public void SignalMemoryTracking(ulong va, ulong size, bool write) + { + // Only the ARM Memory Manager has tracking for now. + } } } diff --git a/Ryujinx.Memory/IVirtualMemoryManager.cs b/Ryujinx.Memory/IVirtualMemoryManager.cs index 8c2296e22..e7e1a9780 100644 --- a/Ryujinx.Memory/IVirtualMemoryManager.cs +++ b/Ryujinx.Memory/IVirtualMemoryManager.cs @@ -23,6 +23,7 @@ namespace Ryujinx.Memory bool IsRangeMapped(ulong va, ulong size); ulong GetPhysicalAddress(ulong va); + void SignalMemoryTracking(ulong va, ulong size, bool write); void TrackingReprotect(ulong va, ulong size, MemoryPermission protection); } }