Fix reprotection regression
This commit is contained in:
parent
6a07f80b76
commit
96d4ad952c
1 changed files with 25 additions and 26 deletions
|
@ -69,6 +69,11 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
{
|
{
|
||||||
_mappings.Add(new RangeNode<ulong>(address, address + size, ulong.MaxValue));
|
_mappings.Add(new RangeNode<ulong>(address, address + size, ulong.MaxValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock (_protections)
|
||||||
|
{
|
||||||
|
_protections.Add(new RangeNode<MemoryPermission>(address, size, MemoryPermission.None));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -104,14 +109,6 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count > 1)
|
|
||||||
{
|
|
||||||
CheckFreeResult(WindowsApi.VirtualFree(
|
|
||||||
(IntPtr)address,
|
|
||||||
(IntPtr)size,
|
|
||||||
AllocationType.Release | AllocationType.CoalescePlaceholders));
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveProtection(address, size);
|
RemoveProtection(address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +127,7 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UnmapViewInternal(sharedMemory, location, size, owner);
|
UnmapViewInternal(sharedMemory, location, size, owner, updateProtection: false);
|
||||||
MapViewInternal(sharedMemory, srcOffset, location, size);
|
MapViewInternal(sharedMemory, srcOffset, location, size);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
@ -166,6 +163,8 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
{
|
{
|
||||||
throw new WindowsApiException("MapViewOfFile3");
|
throw new WindowsApiException("MapViewOfFile3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateProtection((ulong)location, (ulong)size, MemoryPermission.ReadAndWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -189,7 +188,6 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
|
|
||||||
var overlap = overlaps[0];
|
var overlap = overlaps[0];
|
||||||
|
|
||||||
// Tree operations might modify the node start/end values, so save a copy before we modify the tree.
|
|
||||||
ulong overlapStart = overlap.Start;
|
ulong overlapStart = overlap.Start;
|
||||||
ulong overlapEnd = overlap.End;
|
ulong overlapEnd = overlap.End;
|
||||||
ulong overlapValue = overlap.Value;
|
ulong overlapValue = overlap.Value;
|
||||||
|
@ -254,7 +252,7 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UnmapViewInternal(sharedMemory, location, size, owner);
|
UnmapViewInternal(sharedMemory, location, size, owner, updateProtection: true);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -273,8 +271,9 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
/// <param name="location">Address to unmap</param>
|
/// <param name="location">Address to unmap</param>
|
||||||
/// <param name="size">Size of the region to unmap in bytes</param>
|
/// <param name="size">Size of the region to unmap in bytes</param>
|
||||||
/// <param name="owner">Memory block that owns the mapping</param>
|
/// <param name="owner">Memory block that owns the mapping</param>
|
||||||
|
/// <param name="updateProtection">Indicates if the memory protections should be updated after the unmap</param>
|
||||||
/// <exception cref="WindowsApiException">Thrown when the Windows API returns an error unmapping or remapping the memory</exception>
|
/// <exception cref="WindowsApiException">Thrown when the Windows API returns an error unmapping or remapping the memory</exception>
|
||||||
private void UnmapViewInternal(IntPtr sharedMemory, IntPtr location, IntPtr size, MemoryBlock owner)
|
private void UnmapViewInternal(IntPtr sharedMemory, IntPtr location, IntPtr size, MemoryBlock owner, bool updateProtection)
|
||||||
{
|
{
|
||||||
ulong startAddress = (ulong)location;
|
ulong startAddress = (ulong)location;
|
||||||
ulong unmapSize = (ulong)size;
|
ulong unmapSize = (ulong)size;
|
||||||
|
@ -294,7 +293,6 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
|
|
||||||
if (IsMapped(overlap.Value))
|
if (IsMapped(overlap.Value))
|
||||||
{
|
{
|
||||||
// Tree operations might modify the node start/end values, so save a copy before we modify the tree.
|
|
||||||
ulong overlapStart = overlap.Start;
|
ulong overlapStart = overlap.Start;
|
||||||
ulong overlapEnd = overlap.End;
|
ulong overlapEnd = overlap.End;
|
||||||
ulong overlapValue = overlap.Value;
|
ulong overlapValue = overlap.Value;
|
||||||
|
@ -360,7 +358,11 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
}
|
}
|
||||||
|
|
||||||
CoalesceForUnmap(startAddress, unmapSize, owner);
|
CoalesceForUnmap(startAddress, unmapSize, owner);
|
||||||
RemoveProtection(startAddress, unmapSize);
|
|
||||||
|
if (updateProtection)
|
||||||
|
{
|
||||||
|
UpdateProtection(startAddress, unmapSize, MemoryPermission.None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -512,19 +514,10 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
|
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only keep track of "non-standard" protections,
|
|
||||||
// that is, everything that is not just RW (which is the default when views are mapped).
|
|
||||||
if (permission == MemoryPermission.ReadAndWrite)
|
|
||||||
{
|
|
||||||
RemoveProtection(mappedAddress, mappedSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddProtection(mappedAddress, mappedSize, permission);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateProtection(reprotectAddress, reprotectSize, permission);
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,7 +566,7 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
/// <param name="address">Address of the protected region</param>
|
/// <param name="address">Address of the protected region</param>
|
||||||
/// <param name="size">Size of the protected region in bytes</param>
|
/// <param name="size">Size of the protected region in bytes</param>
|
||||||
/// <param name="permission">Memory permissions of the region</param>
|
/// <param name="permission">Memory permissions of the region</param>
|
||||||
private void AddProtection(ulong address, ulong size, MemoryPermission permission)
|
private void UpdateProtection(ulong address, ulong size, MemoryPermission permission)
|
||||||
{
|
{
|
||||||
ulong endAddress = address + size;
|
ulong endAddress = address + size;
|
||||||
var overlaps = new RangeNode<MemoryPermission>[InitialOverlapsSize];
|
var overlaps = new RangeNode<MemoryPermission>[InitialOverlapsSize];
|
||||||
|
@ -693,6 +686,12 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
{
|
{
|
||||||
var protection = overlaps[index];
|
var protection = overlaps[index];
|
||||||
|
|
||||||
|
// If protection is R/W we don't need to reprotect as views are initially mapped as R/W.
|
||||||
|
if (protection.Value == MemoryPermission.ReadAndWrite)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ulong protAddress = protection.Start;
|
ulong protAddress = protection.Start;
|
||||||
ulong protEndAddress = protection.End;
|
ulong protEndAddress = protection.End;
|
||||||
|
|
||||||
|
|
Reference in a new issue