Do not report unmapped pages as dirty (#1672)

* Do not report unmapped pages as dirty

* Make tests pass again

* PR feedback
This commit is contained in:
gdkchan 2020-11-10 22:07:52 -03:00 committed by GitHub
parent 02872833b6
commit 3c60d4b0ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 5 deletions

View file

@ -1,4 +1,4 @@
using ARMeilleure.Memory; using ARMeilleure.Memory;
using Ryujinx.Cpu.Tracking; using Ryujinx.Cpu.Tracking;
using Ryujinx.Memory; using Ryujinx.Memory;
using Ryujinx.Memory.Tracking; using Ryujinx.Memory.Tracking;
@ -461,7 +461,32 @@ namespace Ryujinx.Cpu
} }
/// <summary> /// <summary>
/// Checks if the page at a given CPU virtual address. /// Checks if a memory range is mapped.
/// </summary>
/// <param name="va">Virtual address of the range</param>
/// <param name="size">Size of the range in bytes</param>
/// <returns>True if the entire range is mapped, false otherwise</returns>
public bool IsRangeMapped(ulong va, ulong size)
{
ulong endVa = (va + size + PageMask) & ~(ulong)PageMask;
va &= ~(ulong)PageMask;
while (va < endVa)
{
if (!IsMapped(va))
{
return false;
}
va += PageSize;
}
return true;
}
/// <summary>
/// Checks if the page at a given CPU virtual address is mapped.
/// </summary> /// </summary>
/// <param name="va">Virtual address to check</param> /// <param name="va">Virtual address to check</param>
/// <returns>True if the address is mapped, false otherwise</returns> /// <returns>True if the address is mapped, false otherwise</returns>

View file

@ -15,6 +15,11 @@ namespace Ryujinx.Memory.Tests
return NoMappings ? new (ulong address, ulong size)[0] : new (ulong address, ulong size)[] { (va, size) }; return NoMappings ? new (ulong address, ulong size)[0] : new (ulong address, ulong size)[] { (va, size) };
} }
public bool IsRangeMapped(ulong va, ulong size)
{
return true;
}
public void TrackingReprotect(ulong va, ulong size, MemoryPermission protection) public void TrackingReprotect(ulong va, ulong size, MemoryPermission protection)
{ {

View file

@ -4,6 +4,7 @@
{ {
(ulong address, ulong size)[] GetPhysicalRegions(ulong va, ulong size); (ulong address, ulong size)[] GetPhysicalRegions(ulong va, ulong size);
bool IsRangeMapped(ulong va, ulong size);
void TrackingReprotect(ulong va, ulong size, MemoryPermission protection); void TrackingReprotect(ulong va, ulong size, MemoryPermission protection);
} }
} }

View file

@ -75,6 +75,7 @@ namespace Ryujinx.Memory.Tracking
{ {
VirtualRegion region = results[i]; VirtualRegion region = results[i];
region.RecalculatePhysicalChildren(); region.RecalculatePhysicalChildren();
region.UpdateProtection();
} }
} }
} }
@ -200,7 +201,7 @@ namespace Ryujinx.Memory.Tracking
lock (TrackingLock) lock (TrackingLock)
{ {
RegionHandle handle = new RegionHandle(this, address, size); RegionHandle handle = new RegionHandle(this, address, size, _memoryManager.IsRangeMapped(address, size));
return handle; return handle;
} }

View file

@ -10,7 +10,7 @@ namespace Ryujinx.Memory.Tracking
/// </summary> /// </summary>
public class RegionHandle : IRegionHandle, IRange public class RegionHandle : IRegionHandle, IRange
{ {
public bool Dirty { get; private set; } = true; public bool Dirty { get; private set; }
public ulong Address { get; } public ulong Address { get; }
public ulong Size { get; } public ulong Size { get; }
@ -32,8 +32,10 @@ namespace Ryujinx.Memory.Tracking
/// <param name="tracking">Tracking object for the target memory block</param> /// <param name="tracking">Tracking object for the target memory block</param>
/// <param name="address">Virtual address of the region to track</param> /// <param name="address">Virtual address of the region to track</param>
/// <param name="size">Size of the region to track</param> /// <param name="size">Size of the region to track</param>
internal RegionHandle(MemoryTracking tracking, ulong address, ulong size) /// <param name="dirty">Initial value of the dirty flag</param>
internal RegionHandle(MemoryTracking tracking, ulong address, ulong size, bool dirty = true)
{ {
Dirty = dirty;
Address = address; Address = address;
Size = size; Size = size;
EndAddress = address + size; EndAddress = address + size;