diff --git a/src/Ryujinx.Cpu/Jit/AddressSpacePartition.cs b/src/Ryujinx.Cpu/Jit/AddressSpacePartition.cs index 69d2803206..732de44a36 100644 --- a/src/Ryujinx.Cpu/Jit/AddressSpacePartition.cs +++ b/src/Ryujinx.Cpu/Jit/AddressSpacePartition.cs @@ -208,9 +208,6 @@ namespace Ryujinx.Cpu.Jit private ulong _cachedFirstPagePa; private ulong _cachedLastPagePa; private MemoryBlock _firstPageMemoryForUnmap; - private MemoryBlock _lastPageMemoryForUnmap; - private bool _hasBridgeAtEnd; - private MemoryPermission _lastPageProtection; public ulong Address { get; } public ulong Size { get; } @@ -233,7 +230,6 @@ namespace Ryujinx.Cpu.Jit _cachedFirstPagePa = ulong.MaxValue; _cachedLastPagePa = ulong.MaxValue; - _lastPageProtection = MemoryPermission.ReadAndWrite; Address = address; Size = size; @@ -297,20 +293,6 @@ namespace Ryujinx.Cpu.Jit Debug.Assert(va + size <= EndAddress); _baseMemory.Reprotect(va - Address, size, protection, false); - - if (va + size > EndAddress - _hostPageSize) - { - // Protections at the last page also applies to the bridge, if we have one. - // (This is because last page access is always done on the bridge, not on our base mapping, - // for the cases where access crosses a page boundary and reaches the non-contiguous next mapping). - - if (_hasBridgeAtEnd) - { - _baseMemory.Reprotect(Size, _hostPageSize, protection, false); - } - - _lastPageProtection = protection; - } } public void Reprotect( @@ -325,26 +307,6 @@ namespace Ryujinx.Cpu.Jit LateMap(); } - ulong lastPageAddress = EndAddress - GuestPageSize; - - if (va + size > lastPageAddress) - { - // Protections at the last page also applies to the bridge, if we have one. - // (This is because last page access is always done on the bridge, not on our base mapping, - // for the cases where access crosses a page boundary and reaches the non-contiguous next mapping). - - if (_hasBridgeAtEnd) - { - IntPtr ptPtr = _baseMemory.GetPointerForProtection(Size, _hostPageSize, protection); - - updatePtCallback(lastPageAddress, ptPtr + (IntPtr)(_hostPageSize - GuestPageSize), GuestPageSize); - } - - _lastPageProtection = protection; - - size = lastPageAddress - va; - } - updatePtCallback(va, _baseMemory.GetPointerForProtection(va - Address, size, protection), size); } @@ -353,72 +315,32 @@ namespace Ryujinx.Cpu.Jit Debug.Assert(va >= Address); Debug.Assert(va + size <= EndAddress); - if (va >= EndAddress - GuestPageSize && _hasBridgeAtEnd) - { - return _baseMemory.GetPointer(Size + (_hostPageSize - GuestPageSize), size); - } - return _baseMemory.GetPointer(va - Address, size); } - public void InsertBridgeAtEnd(AddressSpacePartition partitionAfter, Action updatePtCallback, bool useProtectionMirrors) + public void InsertBridgeAtEnd(AddressSpacePartition partitionAfter) { - ulong firstPagePa = partitionAfter._firstPagePa ?? ulong.MaxValue; + ulong firstPagePa = partitionAfter?._firstPagePa ?? ulong.MaxValue; ulong lastPagePa = _lastPagePa ?? ulong.MaxValue; if (firstPagePa != _cachedFirstPagePa || lastPagePa != _cachedLastPagePa) { - if (partitionAfter._firstPagePa.HasValue && _lastPagePa.HasValue) + if (partitionAfter != null && partitionAfter._firstPagePa.HasValue) { (MemoryBlock firstPageMemory, ulong firstPageOffset) = partitionAfter.GetFirstPageMemoryAndOffset(); - (MemoryBlock lastPageMemory, ulong lastPageOffset) = GetLastPageMemoryAndOffset(); - - _baseMemory.MapView(lastPageMemory, lastPageOffset, Size, _hostPageSize); - _baseMemory.MapView(firstPageMemory, firstPageOffset, Size + _hostPageSize, _hostPageSize); - - IntPtr ptPtr; - - if (useProtectionMirrors) - { - ptPtr = _baseMemory.GetPointerForProtection(Size, _hostPageSize, _lastPageProtection); - } - else - { - _baseMemory.Reprotect(Size, _hostPageSize, _lastPageProtection, false); - - ptPtr = _baseMemory.GetPointer(Size, _hostPageSize); - } - - updatePtCallback(EndAddress - GuestPageSize, ptPtr + (IntPtr)(_hostPageSize - GuestPageSize), GuestPageSize); + _baseMemory.MapView(firstPageMemory, firstPageOffset, Size, _hostPageSize); _firstPageMemoryForUnmap = firstPageMemory; - _lastPageMemoryForUnmap = lastPageMemory; - _hasBridgeAtEnd = true; } else { - IntPtr ptPtr = useProtectionMirrors - ? _baseMemory.GetPointerForProtection(Size - _hostPageSize, _hostPageSize, _lastPageProtection) - : _baseMemory.GetPointer(Size - _hostPageSize, _hostPageSize); - - updatePtCallback(EndAddress - GuestPageSize, ptPtr + (IntPtr)(_hostPageSize - GuestPageSize), GuestPageSize); - MemoryBlock firstPageMemoryForUnmap = _firstPageMemoryForUnmap; - MemoryBlock lastPageMemoryForUnmap = _lastPageMemoryForUnmap; if (firstPageMemoryForUnmap != null) { - _baseMemory.UnmapView(firstPageMemoryForUnmap, Size + _hostPageSize, _hostPageSize); + _baseMemory.UnmapView(firstPageMemoryForUnmap, Size, _hostPageSize); _firstPageMemoryForUnmap = null; } - - if (lastPageMemoryForUnmap != null) - { - _baseMemory.UnmapView(lastPageMemoryForUnmap, Size, _hostPageSize); - _lastPageMemoryForUnmap = null; - } - - _hasBridgeAtEnd = false; } _cachedFirstPagePa = firstPagePa; @@ -426,35 +348,6 @@ namespace Ryujinx.Cpu.Jit } } - public void RemoveBridgeFromEnd(Action updatePtCallback, bool useProtectionMirrors) - { - IntPtr ptPtr = useProtectionMirrors - ? _baseMemory.GetPointerForProtection(Size - _hostPageSize, _hostPageSize, _lastPageProtection) - : _baseMemory.GetPointer(Size - _hostPageSize, _hostPageSize); - - updatePtCallback(EndAddress - GuestPageSize, ptPtr + (IntPtr)(_hostPageSize - GuestPageSize), GuestPageSize); - - MemoryBlock firstPageMemoryForUnmap = _firstPageMemoryForUnmap; - MemoryBlock lastPageMemoryForUnmap = _lastPageMemoryForUnmap; - - if (firstPageMemoryForUnmap != null) - { - _baseMemory.UnmapView(firstPageMemoryForUnmap, Size + _hostPageSize, _hostPageSize); - _firstPageMemoryForUnmap = null; - } - - if (lastPageMemoryForUnmap != null) - { - _baseMemory.UnmapView(lastPageMemoryForUnmap, Size, _hostPageSize); - _lastPageMemoryForUnmap = null; - } - - _cachedFirstPagePa = ulong.MaxValue; - _cachedLastPagePa = ulong.MaxValue; - - _hasBridgeAtEnd = false; - } - private (MemoryBlock, ulong) GetFirstPageMemoryAndOffset() { _treeLock.EnterReadLock(); @@ -476,29 +369,6 @@ namespace Ryujinx.Cpu.Jit return (_backingMemory, _firstPagePa.Value); } - private (MemoryBlock, ulong) GetLastPageMemoryAndOffset() - { - _treeLock.EnterReadLock(); - - try - { - ulong pageAddress = EndAddress - _hostPageSize; - - PrivateMapping map = _privateTree.GetNode(pageAddress); - - if (map != null && map.PrivateAllocation.IsValid) - { - return (map.PrivateAllocation.Memory, map.PrivateAllocation.Offset + (pageAddress - map.Address)); - } - } - finally - { - _treeLock.ExitReadLock(); - } - - return (_backingMemory, _lastPagePa.Value & ~(_hostPageSize - 1)); - } - public PrivateRange GetPrivateAllocation(ulong va) { _treeLock.EnterReadLock(); diff --git a/src/Ryujinx.Cpu/Jit/AddressSpacePartitionAllocator.cs b/src/Ryujinx.Cpu/Jit/AddressSpacePartitionAllocator.cs index 5bb7947023..8a8b6814a3 100644 --- a/src/Ryujinx.Cpu/Jit/AddressSpacePartitionAllocator.cs +++ b/src/Ryujinx.Cpu/Jit/AddressSpacePartitionAllocator.cs @@ -23,9 +23,9 @@ namespace Ryujinx.Cpu.Jit _allocation = allocation; } - public void RegisterMapping(ulong va, ulong endVa, int bridgeSize) + public void RegisterMapping(ulong va, ulong endVa) { - _allocation.Block.AddMapping(_allocation.Offset, _allocation.Size, va, endVa, bridgeSize); + _allocation.Block.AddMapping(_allocation.Offset, _allocation.Size, va, endVa); } public void MapView(MemoryBlock srcBlock, ulong srcOffset, ulong dstOffset, ulong size) @@ -72,15 +72,13 @@ namespace Ryujinx.Cpu.Jit public ulong EndAddress => Address + Size; public ulong Va { get; } public ulong EndVa { get; } - public int BridgeSize { get; } - public Mapping(ulong address, ulong size, ulong va, ulong endVa, int bridgeSize) + public Mapping(ulong address, ulong size, ulong va, ulong endVa) { Address = address; Size = size; Va = va; EndVa = endVa; - BridgeSize = bridgeSize; } public int CompareTo(Mapping other) @@ -128,9 +126,9 @@ namespace Ryujinx.Cpu.Jit _lock = locker; } - public void AddMapping(ulong offset, ulong size, ulong va, ulong endVa, int bridgeSize) + public void AddMapping(ulong offset, ulong size, ulong va, ulong endVa) { - _mappingTree.Add(new(offset, size, va, endVa, bridgeSize)); + _mappingTree.Add(new(offset, size, va, endVa)); } public void RemoveMapping(ulong offset, ulong size) @@ -154,11 +152,6 @@ namespace Ryujinx.Cpu.Jit address -= map.Address; - if (address >= (map.EndVa - map.Va)) - { - address -= (ulong)(map.BridgeSize / 2); - } - ulong addressAligned = BitUtils.AlignDown(address, AddressSpacePartition.GuestPageSize); ulong endAddressAligned = BitUtils.AlignUp(address + size, AddressSpacePartition.GuestPageSize); ulong sizeAligned = endAddressAligned - addressAligned; @@ -193,18 +186,10 @@ namespace Ryujinx.Cpu.Jit _lock = locker; } - public AddressSpacePartitionAllocation Allocate(ulong va, ulong size, int bridgeSize) - { - AddressSpacePartitionAllocation allocation = new(this, Allocate(size + (ulong)bridgeSize, MemoryBlock.GetPageSize(), CreateBlock)); - allocation.RegisterMapping(va, va + size, bridgeSize); - - return allocation; - } - - public AddressSpacePartitionAllocation AllocatePage(ulong va, ulong size) + public AddressSpacePartitionAllocation Allocate(ulong va, ulong size) { AddressSpacePartitionAllocation allocation = new(this, Allocate(size, MemoryBlock.GetPageSize(), CreateBlock)); - allocation.RegisterMapping(va, va + size, 0); + allocation.RegisterMapping(va, va + size); return allocation; } diff --git a/src/Ryujinx.Cpu/Jit/AddressSpacePartitioned.cs b/src/Ryujinx.Cpu/Jit/AddressSpacePartitioned.cs index ba44299e19..244dd0e75b 100644 --- a/src/Ryujinx.Cpu/Jit/AddressSpacePartitioned.cs +++ b/src/Ryujinx.Cpu/Jit/AddressSpacePartitioned.cs @@ -49,7 +49,7 @@ namespace Ryujinx.Cpu.Jit va += currentSize; pa += currentSize; - InsertBridgeIfNeeded(partitionIndex); + InsertOrRemoveBridgeIfNeeded(partitionIndex); } } } @@ -80,7 +80,7 @@ namespace Ryujinx.Cpu.Jit va += clampedEndVa - clampedVa; - RemoveBridgeIfNeeded(partitionIndex); + InsertOrRemoveBridgeIfNeeded(partitionIndex); if (partition.IsEmpty()) { @@ -181,33 +181,27 @@ namespace Ryujinx.Cpu.Jit return false; } - private void InsertBridgeIfNeeded(int partitionIndex) + private void InsertOrRemoveBridgeIfNeeded(int partitionIndex) { - if (partitionIndex > 0 && _partitions[partitionIndex - 1].EndAddress == _partitions[partitionIndex].Address) + if (partitionIndex > 0) { - _partitions[partitionIndex - 1].InsertBridgeAtEnd(_partitions[partitionIndex], _updatePtCallback, _useProtectionMirrors); + if (_partitions[partitionIndex - 1].EndAddress == _partitions[partitionIndex].Address) + { + _partitions[partitionIndex - 1].InsertBridgeAtEnd(_partitions[partitionIndex]); + } + else + { + _partitions[partitionIndex - 1].InsertBridgeAtEnd(null); + } } if (partitionIndex + 1 < _partitions.Count && _partitions[partitionIndex].EndAddress == _partitions[partitionIndex + 1].Address) { - _partitions[partitionIndex].InsertBridgeAtEnd(_partitions[partitionIndex + 1], _updatePtCallback, _useProtectionMirrors); - } - } - - private void RemoveBridgeIfNeeded(int partitionIndex) - { - if (partitionIndex > 0 && _partitions[partitionIndex - 1].EndAddress == _partitions[partitionIndex].Address) - { - _partitions[partitionIndex - 1].InsertBridgeAtEnd(_partitions[partitionIndex], _updatePtCallback, _useProtectionMirrors); - } - - if (partitionIndex + 1 < _partitions.Count && _partitions[partitionIndex].EndAddress == _partitions[partitionIndex + 1].Address) - { - _partitions[partitionIndex].InsertBridgeAtEnd(_partitions[partitionIndex + 1], _updatePtCallback, _useProtectionMirrors); + _partitions[partitionIndex].InsertBridgeAtEnd(_partitions[partitionIndex + 1]); } else { - _partitions[partitionIndex].RemoveBridgeFromEnd(_updatePtCallback, _useProtectionMirrors); + _partitions[partitionIndex].InsertBridgeAtEnd(null); } } @@ -360,9 +354,7 @@ namespace Ryujinx.Cpu.Jit public AddressSpacePartitionAllocation CreateAsPartitionAllocation(ulong va, ulong size) { - ulong bridgeSize = MemoryBlock.GetPageSize() * 2; - - return _asAllocator.Allocate(va, size, (int)bridgeSize); + return _asAllocator.Allocate(va, size + MemoryBlock.GetPageSize()); } protected virtual void Dispose(bool disposing)