From cb2b0f455e10e408d6171fd1811d4a55d743e41c Mon Sep 17 00:00:00 2001 From: _Neo_ Date: Sat, 23 May 2026 22:34:19 +0300 Subject: [PATCH] Attempt fix other bug --- src/Ryujinx.Cpu/Jit/MemoryManager.cs | 65 ++++++++++++++-------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/src/Ryujinx.Cpu/Jit/MemoryManager.cs b/src/Ryujinx.Cpu/Jit/MemoryManager.cs index 8cc786a83..8b9ef7aca 100644 --- a/src/Ryujinx.Cpu/Jit/MemoryManager.cs +++ b/src/Ryujinx.Cpu/Jit/MemoryManager.cs @@ -1,4 +1,5 @@ using ARMeilleure.Memory; +using Ryujinx.Common.Logging; using Ryujinx.Memory; using Ryujinx.Memory.Range; using Ryujinx.Memory.Tracking; @@ -17,33 +18,19 @@ namespace Ryujinx.Cpu.Jit public sealed class MemoryManager : VirtualMemoryManagerRefCountedBase, IMemoryManager, IVirtualMemoryManagerTracked { private const int PteSize = 8; - private const int PointerTagBit = 62; - private readonly MemoryBlock _backingMemory; private readonly InvalidAccessHandler _invalidAccessHandler; - /// + private long _invalidAccessCount = 0; public bool UsesPrivateAllocations => false; - - /// - /// Address space width in bits. - /// public int AddressSpaceBits { get; } - + public nint PageTablePointer => (nint)_pageTable.Pointer; private readonly MemoryBlock _pageTable; - private readonly ManagedPageFlags _pages; - /// - /// Page table base pointer. - /// - public nint PageTablePointer => _pageTable.Pointer; - public MemoryManagerType Type => MemoryManagerType.SoftwarePageTable; - public MemoryTracking Tracking { get; } - public event Action UnmapEvent; protected override ulong AddressSpaceSize { get; } @@ -61,22 +48,24 @@ namespace Ryujinx.Cpu.Jit ulong asSize = PageSize; int asBits = PageBits; - while (asSize < addressSpaceSize) { asSize <<= 1; asBits++; } - AddressSpaceBits = asBits; AddressSpaceSize = asSize; + _pageTable = new MemoryBlock((asSize / PageSize) * PteSize); - _pages = new ManagedPageFlags(AddressSpaceBits); - Tracking = new MemoryTracking(this, PageSize); } + private static bool IsPoisonedPointer(ulong addr) + { + return addr == 0 || (addr & 0x6969696969696969UL) != 0; + } + /// public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags) { @@ -145,16 +134,21 @@ namespace Ryujinx.Cpu.Jit try { SignalMemoryTrackingImpl(va, (ulong)Unsafe.SizeOf(), false, true); - return Read(va); } catch (InvalidMemoryRegionException) { - if (_invalidAccessHandler == null || !_invalidAccessHandler(va)) + if (IsPoisonedPointer(va)) { - throw; + if (Interlocked.Increment(ref _invalidAccessCount) % 4096 == 0) + { + Logger.Warning?.Print(LogClass.Cpu, $"[TOTK Mod Tolerant] Suppressed poisoned read @ 0x{va:X16}"); + } + return default; } + if (_invalidAccessHandler == null || !_invalidAccessHandler(va)) + throw; return default; } } @@ -168,18 +162,20 @@ namespace Ryujinx.Cpu.Jit } catch (InvalidMemoryRegionException) { - if (_invalidAccessHandler == null || !_invalidAccessHandler(va)) + if (IsPoisonedPointer(va)) { - throw; + if (Interlocked.Increment(ref _invalidAccessCount) % 4096 == 0) + { + Logger.Warning?.Print(LogClass.Cpu, $"[TOTK Mod Tolerant] Suppressed poisoned read @ 0x{va:X16}"); + } + data.Clear(); + return; } + + if (_invalidAccessHandler == null || !_invalidAccessHandler(va)) + throw; } } - - public override bool TryReadUnsafe(ulong va, int length, out Span data) - { - throw new NotImplementedException(); - } - public override void Write(ulong va, ReadOnlySpan data) { try @@ -188,10 +184,13 @@ namespace Ryujinx.Cpu.Jit } catch (InvalidMemoryRegionException) { - if (_invalidAccessHandler == null || !_invalidAccessHandler(va)) + if (IsPoisonedPointer(va)) { - throw; + return; // silently ignore writes to poisoned memory } + + if (_invalidAccessHandler == null || !_invalidAccessHandler(va)) + throw; } }