From 1dd2d68be83b3029c8b03b522773a1e068b5f99b Mon Sep 17 00:00:00 2001 From: gdk Date: Thu, 12 Jan 2023 23:12:11 -0300 Subject: [PATCH] Minor refactoring of KPageTableBase to make custom address space layouts easier to implement (cherry picked from commit a29acdb593f4426d5a05cf1659ace11361378638) --- .../HOS/Kernel/Memory/KPageTableBase.cs | 63 ++++++++----------- .../HOS/Kernel/SupervisorCall/Syscall.cs | 10 +-- .../HOS/Services/Ro/IRoInterface.cs | 4 +- 3 files changed, 33 insertions(+), 44 deletions(-) diff --git a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs index bf2bbb97b..d6a54e8ee 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs @@ -35,8 +35,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory protected readonly KernelContext Context; protected virtual bool UsesPrivateAllocations => false; - public ulong AddrSpaceStart { get; private set; } - public ulong AddrSpaceEnd { get; private set; } + public ulong AddressSpaceStart { get; private set; } + public ulong AddressSpaceEnd { get; private set; } public ulong CodeRegionStart { get; private set; } public ulong CodeRegionEnd { get; private set; } @@ -68,6 +68,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory private MemoryRegion _memRegion; private bool _allocateFromBack; + private readonly bool _isKernel; private bool _aslrEnabled; @@ -284,8 +285,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory _aslrEnabled = aslrEnabled; - AddrSpaceStart = addrSpaceStart; - AddrSpaceEnd = addrSpaceEnd; + AddressSpaceStart = addrSpaceStart; + AddressSpaceEnd = addrSpaceEnd; _slabManager = slabManager; @@ -308,10 +309,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory aliasRegion.End = aliasRegion.Start + aliasRegion.Size; heapRegion.Start = mapBaseAddress + heapRegion.AslrOffset; heapRegion.End = heapRegion.Start + heapRegion.Size; - stackRegion.Start = mapBaseAddress + stackRegion.AslrOffset; - stackRegion.End = stackRegion.Start + stackRegion.Size; - tlsIoRegion.Start = mapBaseAddress + tlsIoRegion.AslrOffset; - tlsIoRegion.End = tlsIoRegion.Start + tlsIoRegion.Size; SortRegion(ref aliasRegion, ref heapRegion, true); @@ -438,9 +435,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory ulong endAddr = address + size; - ulong addrSpacePagesCount = (AddrSpaceEnd - AddrSpaceStart) / PageSize; + ulong addrSpacePagesCount = (AddressSpaceEnd - AddressSpaceStart) / PageSize; - if (AddrSpaceStart > address) + if (AddressSpaceStart > address) { return KernelResult.InvalidMemState; } @@ -450,7 +447,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory return KernelResult.InvalidMemState; } - if (endAddr - 1 > AddrSpaceEnd - 1) + if (endAddr - 1 > AddressSpaceEnd - 1) { return KernelResult.InvalidMemState; } @@ -983,8 +980,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory public KMemoryInfo QueryMemory(ulong address) { - if (address >= AddrSpaceStart && - address < AddrSpaceEnd) + if (address >= AddressSpaceStart && + address < AddressSpaceEnd) { lock (_blockManager) { @@ -994,8 +991,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory else { return new KMemoryInfo( - AddrSpaceEnd, - ~AddrSpaceEnd + 1, + AddressSpaceEnd, + ~AddressSpaceEnd + 1, MemoryState.Reserved, KMemoryPermission.None, MemoryAttribute.None, @@ -1557,14 +1554,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory MemoryAttribute attributeExpected, bool toServer) { - if (AddrSpaceStart > clientAddress) + if (AddressSpaceStart > clientAddress) { return KernelResult.InvalidMemState; } ulong srcEndAddr = clientAddress + size; - if (srcEndAddr <= clientAddress || srcEndAddr - 1 > AddrSpaceEnd - 1) + if (srcEndAddr <= clientAddress || srcEndAddr - 1 > AddressSpaceEnd - 1) { return KernelResult.InvalidMemState; } @@ -1688,14 +1685,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory { blocksNeeded = 0; - if (AddrSpaceStart > address) + if (AddressSpaceStart > address) { return KernelResult.InvalidMemState; } ulong endAddr = address + size; - if (endAddr <= address || endAddr - 1 > AddrSpaceEnd - 1) + if (endAddr <= address || endAddr - 1 > AddressSpaceEnd - 1) { return KernelResult.InvalidMemState; } @@ -2028,14 +2025,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory public Result UnmapNoAttributeIfStateEquals(ulong address, ulong size, MemoryState state) { - if (AddrSpaceStart > address) + if (AddressSpaceStart > address) { return KernelResult.InvalidMemState; } ulong endAddr = address + size; - if (endAddr <= address || endAddr - 1 > AddrSpaceEnd - 1) + if (endAddr <= address || endAddr - 1 > AddressSpaceEnd - 1) { return KernelResult.InvalidMemState; } @@ -2809,7 +2806,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory case MemoryState.ProcessMemory: case MemoryState.CodeReadOnly: case MemoryState.CodeWritable: - return GetAddrSpaceBaseAddr(); + return AslrRegionStart; case MemoryState.Heap: return HeapRegionStart; @@ -2823,7 +2820,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory return StackRegionStart; case MemoryState.KernelStack: - return AddrSpaceStart; + return AddressSpaceStart; } throw new ArgumentException($"Invalid state value \"{state}\"."); @@ -2848,7 +2845,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory case MemoryState.ProcessMemory: case MemoryState.CodeReadOnly: case MemoryState.CodeWritable: - return GetAddrSpaceSize(); + return AslrRegionEnd - AslrRegionStart; case MemoryState.Heap: return HeapRegionEnd - HeapRegionStart; @@ -2862,22 +2859,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory return StackRegionEnd - StackRegionStart; case MemoryState.KernelStack: - return AddrSpaceEnd - AddrSpaceStart; + return AddressSpaceEnd - AddressSpaceStart; } throw new ArgumentException($"Invalid state value \"{state}\"."); } - public ulong GetAddrSpaceBaseAddr() - { - return AslrRegionStart; - } - - public ulong GetAddrSpaceSize() - { - return AslrRegionEnd - AslrRegionStart; - } - private static ulong GetDramAddressFromPa(ulong pa) { return pa - DramMemoryMap.DramBase; @@ -2903,12 +2890,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory public bool IsInvalidRegion(ulong address, ulong size) { - return address + size - 1 > GetAddrSpaceBaseAddr() + GetAddrSpaceSize() - 1; + return address + size - 1 > AslrRegionEnd - 1; } public bool InsideAddrSpace(ulong address, ulong size) { - return AddrSpaceStart <= address && address + size - 1 <= AddrSpaceEnd - 1; + return AddressSpaceStart <= address && address + size - 1 <= AddressSpaceEnd - 1; } public bool InsideAliasRegion(ulong address, ulong size) @@ -2933,7 +2920,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory public bool OutsideAddrSpace(ulong address, ulong size) { - return AddrSpaceStart > address || address + size - 1 > AddrSpaceEnd - 1; + return AddressSpaceStart > address || address + size - 1 > AddressSpaceEnd - 1; } public bool OutsideStackRegion(ulong address, ulong size) diff --git a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs index 2f487243d..03f64ebcf 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs @@ -1976,6 +1976,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall case InfoType.HeapRegionAddress: value = process.MemoryManager.HeapRegionStart; break; + case InfoType.HeapRegionSize: value = process.MemoryManager.HeapRegionEnd - process.MemoryManager.HeapRegionStart; break; @@ -1988,15 +1989,16 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall break; case InfoType.AslrRegionAddress: - value = process.MemoryManager.GetAddrSpaceBaseAddr(); + value = process.MemoryManager.AslrRegionStart; break; case InfoType.AslrRegionSize: - value = process.MemoryManager.GetAddrSpaceSize(); + value = process.MemoryManager.AslrRegionEnd - process.MemoryManager.AslrRegionStart; break; case InfoType.StackRegionAddress: value = process.MemoryManager.StackRegionStart; break; + case InfoType.StackRegionSize: value = process.MemoryManager.StackRegionEnd - process.MemoryManager.StackRegionStart; break; @@ -2813,7 +2815,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { KProcess currentProcess = KernelStatic.GetCurrentProcess(); - if (currentProcess.MemoryManager.AddrSpaceStart > handlesPtr) + if (currentProcess.MemoryManager.AddressSpaceStart > handlesPtr) { return KernelResult.UserCopyFailed; } @@ -2825,7 +2827,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.UserCopyFailed; } - if (handlesPtr + (ulong)handlesSize - 1 > currentProcess.MemoryManager.AddrSpaceEnd - 1) + if (handlesPtr + (ulong)handlesSize - 1 > currentProcess.MemoryManager.AddressSpaceEnd - 1) { return KernelResult.UserCopyFailed; } diff --git a/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs b/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs index 5b5b3bf84..e5110ca7d 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ro/IRoInterface.cs @@ -270,7 +270,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro int retryCount; - ulong addressSpacePageLimit = (memMgr.GetAddrSpaceSize() - size) >> 12; + ulong addressSpacePageLimit = ((memMgr.AslrRegionEnd - memMgr.AslrRegionStart) - size) >> 12; for (retryCount = 0; retryCount < MaxMapRetries; retryCount++) { @@ -278,7 +278,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro { ulong randomOffset = (ulong)(uint)Random.Shared.Next(0, (int)addressSpacePageLimit) << 12; - targetAddress = memMgr.GetAddrSpaceBaseAddr() + randomOffset; + targetAddress = memMgr.AslrRegionStart + randomOffset; if (memMgr.InsideAddrSpace(targetAddress, size) && !memMgr.InsideHeapRegion(targetAddress, size) && !memMgr.InsideAliasRegion(targetAddress, size)) {