Minor refactoring of KPageTableBase to make custom address space layouts easier to implement

This commit is contained in:
gdk 2023-01-12 23:12:11 -03:00 committed by Emmanuel Hansen
parent c5bcdc06f5
commit a1e34041fa
3 changed files with 36 additions and 50 deletions

View File

@ -34,8 +34,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
protected readonly KernelContext Context; protected readonly KernelContext Context;
protected virtual bool Supports4KBPages => true; protected virtual bool Supports4KBPages => true;
public ulong AddrSpaceStart { get; private set; } public ulong AddressSpaceStart { get; private set; }
public ulong AddrSpaceEnd { get; private set; } public ulong AddressSpaceEnd { get; private set; }
public ulong CodeRegionStart { get; private set; } public ulong CodeRegionStart { get; private set; }
public ulong CodeRegionEnd { get; private set; } public ulong CodeRegionEnd { get; private set; }
@ -68,6 +68,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
private MemoryRegion _memRegion; private MemoryRegion _memRegion;
private bool _allocateFromBack; private bool _allocateFromBack;
private readonly bool _isKernel; private readonly bool _isKernel;
private bool _aslrEnabled; private bool _aslrEnabled;
@ -267,8 +268,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
_aslrEnabled = aslrEnabled; _aslrEnabled = aslrEnabled;
AddrSpaceStart = addrSpaceStart; AddressSpaceStart = addrSpaceStart;
AddrSpaceEnd = addrSpaceEnd; AddressSpaceEnd = addrSpaceEnd;
_slabManager = slabManager; _slabManager = slabManager;
@ -291,10 +292,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
aliasRegion.End = aliasRegion.Start + aliasRegion.Size; aliasRegion.End = aliasRegion.Start + aliasRegion.Size;
heapRegion.Start = mapBaseAddress + heapRegion.AslrOffset; heapRegion.Start = mapBaseAddress + heapRegion.AslrOffset;
heapRegion.End = heapRegion.Start + heapRegion.Size; 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); SortRegion(ref aliasRegion, ref heapRegion, true);
@ -421,9 +418,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
ulong endAddr = address + size; ulong endAddr = address + size;
ulong addrSpacePagesCount = (AddrSpaceEnd - AddrSpaceStart) / PageSize; ulong addrSpacePagesCount = (AddressSpaceEnd - AddressSpaceStart) / PageSize;
if (AddrSpaceStart > address) if (AddressSpaceStart > address)
{ {
return KernelResult.InvalidMemState; return KernelResult.InvalidMemState;
} }
@ -433,7 +430,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
return KernelResult.InvalidMemState; return KernelResult.InvalidMemState;
} }
if (endAddr - 1 > AddrSpaceEnd - 1) if (endAddr - 1 > AddressSpaceEnd - 1)
{ {
return KernelResult.InvalidMemState; return KernelResult.InvalidMemState;
} }
@ -966,8 +963,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
public KMemoryInfo QueryMemory(ulong address) public KMemoryInfo QueryMemory(ulong address)
{ {
if (address >= AddrSpaceStart && if (address >= AddressSpaceStart &&
address < AddrSpaceEnd) address < AddressSpaceEnd)
{ {
lock (_blockManager) lock (_blockManager)
{ {
@ -977,8 +974,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
else else
{ {
return new KMemoryInfo( return new KMemoryInfo(
AddrSpaceEnd, AddressSpaceEnd,
~AddrSpaceEnd + 1, ~AddressSpaceEnd + 1,
MemoryState.Reserved, MemoryState.Reserved,
KMemoryPermission.None, KMemoryPermission.None,
MemoryAttribute.None, MemoryAttribute.None,
@ -1540,14 +1537,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
MemoryAttribute attributeExpected, MemoryAttribute attributeExpected,
bool toServer) bool toServer)
{ {
if (AddrSpaceStart > clientAddress) if (AddressSpaceStart > clientAddress)
{ {
return KernelResult.InvalidMemState; return KernelResult.InvalidMemState;
} }
ulong srcEndAddr = clientAddress + size; ulong srcEndAddr = clientAddress + size;
if (srcEndAddr <= clientAddress || srcEndAddr - 1 > AddrSpaceEnd - 1) if (srcEndAddr <= clientAddress || srcEndAddr - 1 > AddressSpaceEnd - 1)
{ {
return KernelResult.InvalidMemState; return KernelResult.InvalidMemState;
} }
@ -1671,14 +1668,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
{ {
blocksNeeded = 0; blocksNeeded = 0;
if (AddrSpaceStart > address) if (AddressSpaceStart > address)
{ {
return KernelResult.InvalidMemState; return KernelResult.InvalidMemState;
} }
ulong endAddr = address + size; ulong endAddr = address + size;
if (endAddr <= address || endAddr - 1 > AddrSpaceEnd - 1) if (endAddr <= address || endAddr - 1 > AddressSpaceEnd - 1)
{ {
return KernelResult.InvalidMemState; return KernelResult.InvalidMemState;
} }
@ -2011,14 +2008,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
public Result UnmapNoAttributeIfStateEquals(ulong address, ulong size, MemoryState state) public Result UnmapNoAttributeIfStateEquals(ulong address, ulong size, MemoryState state)
{ {
if (AddrSpaceStart > address) if (AddressSpaceStart > address)
{ {
return KernelResult.InvalidMemState; return KernelResult.InvalidMemState;
} }
ulong endAddr = address + size; ulong endAddr = address + size;
if (endAddr <= address || endAddr - 1 > AddrSpaceEnd - 1) if (endAddr <= address || endAddr - 1 > AddressSpaceEnd - 1)
{ {
return KernelResult.InvalidMemState; return KernelResult.InvalidMemState;
} }
@ -2792,7 +2789,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
case MemoryState.ProcessMemory: case MemoryState.ProcessMemory:
case MemoryState.CodeReadOnly: case MemoryState.CodeReadOnly:
case MemoryState.CodeWritable: case MemoryState.CodeWritable:
return GetAddrSpaceBaseAddr(); return AslrRegionStart;
case MemoryState.Heap: case MemoryState.Heap:
return HeapRegionStart; return HeapRegionStart;
@ -2806,7 +2803,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
return StackRegionStart; return StackRegionStart;
case MemoryState.KernelStack: case MemoryState.KernelStack:
return AddrSpaceStart; return AddressSpaceStart;
} }
throw new ArgumentException($"Invalid state value \"{state}\"."); throw new ArgumentException($"Invalid state value \"{state}\".");
@ -2831,7 +2828,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
case MemoryState.ProcessMemory: case MemoryState.ProcessMemory:
case MemoryState.CodeReadOnly: case MemoryState.CodeReadOnly:
case MemoryState.CodeWritable: case MemoryState.CodeWritable:
return GetAddrSpaceSize(); return AslrRegionEnd - AslrRegionStart;
case MemoryState.Heap: case MemoryState.Heap:
return HeapRegionEnd - HeapRegionStart; return HeapRegionEnd - HeapRegionStart;
@ -2845,22 +2842,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
return StackRegionEnd - StackRegionStart; return StackRegionEnd - StackRegionStart;
case MemoryState.KernelStack: case MemoryState.KernelStack:
return AddrSpaceEnd - AddrSpaceStart; return AddressSpaceEnd - AddressSpaceStart;
} }
throw new ArgumentException($"Invalid state value \"{state}\"."); throw new ArgumentException($"Invalid state value \"{state}\".");
} }
public ulong GetAddrSpaceBaseAddr()
{
return AslrRegionStart;
}
public ulong GetAddrSpaceSize()
{
return AslrRegionEnd - AslrRegionStart;
}
private static ulong GetDramAddressFromPa(ulong pa) private static ulong GetDramAddressFromPa(ulong pa)
{ {
return pa - DramMemoryMap.DramBase; return pa - DramMemoryMap.DramBase;
@ -2886,12 +2873,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
public bool IsInvalidRegion(ulong address, ulong size) 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) 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) public bool InsideAliasRegion(ulong address, ulong size)
@ -2916,7 +2903,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
public bool OutsideAddrSpace(ulong address, ulong size) 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) public bool OutsideStackRegion(ulong address, ulong size)

View File

@ -2005,16 +2005,15 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
value = process.MemoryManager.AliasRegionStart; value = process.MemoryManager.AliasRegionStart;
break; break;
case InfoType.AliasRegionSize: case InfoType.AliasRegionSize:
value = (process.MemoryManager.AliasRegionEnd - value = process.MemoryManager.AliasRegionEnd - process.MemoryManager.AliasRegionStart;
process.MemoryManager.AliasRegionStart);
break; break;
case InfoType.HeapRegionAddress: case InfoType.HeapRegionAddress:
value = process.MemoryManager.HeapRegionStart; value = process.MemoryManager.HeapRegionStart;
break; break;
case InfoType.HeapRegionSize: case InfoType.HeapRegionSize:
value = (process.MemoryManager.HeapRegionEnd - value = process.MemoryManager.HeapRegionEnd - process.MemoryManager.HeapRegionStart;
process.MemoryManager.HeapRegionStart);
break; break;
case InfoType.TotalMemorySize: case InfoType.TotalMemorySize:
@ -2026,19 +2025,19 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
break; break;
case InfoType.AslrRegionAddress: case InfoType.AslrRegionAddress:
value = process.MemoryManager.GetAddrSpaceBaseAddr(); value = process.MemoryManager.AslrRegionStart;
break; break;
case InfoType.AslrRegionSize: case InfoType.AslrRegionSize:
value = process.MemoryManager.GetAddrSpaceSize(); value = process.MemoryManager.AslrRegionEnd - process.MemoryManager.AslrRegionStart;
break; break;
case InfoType.StackRegionAddress: case InfoType.StackRegionAddress:
value = process.MemoryManager.StackRegionStart; value = process.MemoryManager.StackRegionStart;
break; break;
case InfoType.StackRegionSize: case InfoType.StackRegionSize:
value = (process.MemoryManager.StackRegionEnd - value = process.MemoryManager.StackRegionEnd - process.MemoryManager.StackRegionStart;
process.MemoryManager.StackRegionStart);
break; break;
case InfoType.SystemResourceSizeTotal: case InfoType.SystemResourceSizeTotal:
@ -2872,7 +2871,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{ {
KProcess currentProcess = KernelStatic.GetCurrentProcess(); KProcess currentProcess = KernelStatic.GetCurrentProcess();
if (currentProcess.MemoryManager.AddrSpaceStart > handlesPtr) if (currentProcess.MemoryManager.AddressSpaceStart > handlesPtr)
{ {
return KernelResult.UserCopyFailed; return KernelResult.UserCopyFailed;
} }
@ -2884,7 +2883,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.UserCopyFailed; return KernelResult.UserCopyFailed;
} }
if (handlesPtr + (ulong)handlesSize - 1 > currentProcess.MemoryManager.AddrSpaceEnd - 1) if (handlesPtr + (ulong)handlesSize - 1 > currentProcess.MemoryManager.AddressSpaceEnd - 1)
{ {
return KernelResult.UserCopyFailed; return KernelResult.UserCopyFailed;
} }

View File

@ -270,7 +270,7 @@ namespace Ryujinx.HLE.HOS.Services.Ro
int retryCount; int retryCount;
ulong addressSpacePageLimit = (memMgr.GetAddrSpaceSize() - size) >> 12; ulong addressSpacePageLimit = ((memMgr.AslrRegionEnd - memMgr.AslrRegionStart) - size) >> 12;
for (retryCount = 0; retryCount < MaxMapRetries; retryCount++) 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; 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)) if (memMgr.InsideAddrSpace(targetAddress, size) && !memMgr.InsideHeapRegion(targetAddress, size) && !memMgr.InsideAliasRegion(targetAddress, size))
{ {