From 1e687c4eea8832cc12828cedb538f53da88f2042 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 6 May 2020 09:48:57 -0300 Subject: [PATCH] Fix block iteration on kernel MemoryManager InsertBlock function (#1184) --- .../HOS/Kernel/Memory/KMemoryManager.cs | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs index 77f190c43a..c7b95fbf0c 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs @@ -2420,9 +2420,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory while (node != null) { - KMemoryBlock currBlock = node.Value; + LinkedListNode newNode = node; - LinkedListNode nextNode = node.Next; + KMemoryBlock currBlock = node.Value; ulong currBaseAddr = currBlock.BaseAddress; ulong currEndAddr = currBlock.PagesCount * PageSize + currBaseAddr; @@ -2435,13 +2435,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory currBlock.Permission != oldPermission || currBlockAttr != oldAttribute) { - node = nextNode; + node = node.Next; continue; } - LinkedListNode newNode = node; - if (baseAddress > currBaseAddr) { _blocks.AddBefore(node, currBlock.SplitRightAtAddress(baseAddress)); @@ -2454,7 +2452,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory newNode.Value.SetState(newPermission, newState, newAttribute); - MergeEqualStateNeighbors(newNode); + newNode = MergeEqualStateNeighbors(newNode); } if (currEndAddr - 1 >= endAddr - 1) @@ -2462,7 +2460,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory break; } - node = nextNode; + node = newNode.Next; } _blockAllocator.Count += _blocks.Count - oldCount; @@ -2485,17 +2483,15 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory while (node != null) { - KMemoryBlock currBlock = node.Value; + LinkedListNode newNode = node; - LinkedListNode nextNode = node.Next; + KMemoryBlock currBlock = node.Value; ulong currBaseAddr = currBlock.BaseAddress; ulong currEndAddr = currBlock.PagesCount * PageSize + currBaseAddr; if (baseAddress < currEndAddr && currBaseAddr < endAddr) { - LinkedListNode newNode = node; - if (baseAddress > currBaseAddr) { _blocks.AddBefore(node, currBlock.SplitRightAtAddress(baseAddress)); @@ -2508,7 +2504,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory newNode.Value.SetState(permission, state, attribute); - MergeEqualStateNeighbors(newNode); + newNode = MergeEqualStateNeighbors(newNode); } if (currEndAddr - 1 >= endAddr - 1) @@ -2516,7 +2512,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory break; } - node = nextNode; + node = newNode.Next; } _blockAllocator.Count += _blocks.Count - oldCount; @@ -2551,17 +2547,15 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory while (node != null) { - KMemoryBlock currBlock = node.Value; + LinkedListNode newNode = node; - LinkedListNode nextNode = node.Next; + KMemoryBlock currBlock = node.Value; ulong currBaseAddr = currBlock.BaseAddress; ulong currEndAddr = currBlock.PagesCount * PageSize + currBaseAddr; if (baseAddress < currEndAddr && currBaseAddr < endAddr) { - LinkedListNode newNode = node; - if (baseAddress > currBaseAddr) { _blocks.AddBefore(node, currBlock.SplitRightAtAddress(baseAddress)); @@ -2576,7 +2570,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory blockMutate(newBlock, permission); - MergeEqualStateNeighbors(newNode); + newNode = MergeEqualStateNeighbors(newNode); } if (currEndAddr - 1 >= endAddr - 1) @@ -2584,13 +2578,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory break; } - node = nextNode; + node = newNode.Next; } _blockAllocator.Count += _blocks.Count - oldCount; } - private void MergeEqualStateNeighbors(LinkedListNode node) + private LinkedListNode MergeEqualStateNeighbors(LinkedListNode node) { KMemoryBlock block = node.Value; @@ -2622,6 +2616,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory block.AddPages(nextBlock.PagesCount); } } + + return node; } private static bool BlockStateEquals(KMemoryBlock lhs, KMemoryBlock rhs)