Implement kernel GetInfo AliasRegionExtraSize

This commit is contained in:
Gabriel A 2024-07-20 15:08:28 -03:00
commit b37f7caacb
6 changed files with 73 additions and 70 deletions

View file

@ -1,10 +0,0 @@
namespace Ryujinx.HLE.HOS.Kernel.Memory
{
enum AddressSpaceType
{
Addr32Bits = 0,
Addr36Bits = 1,
Addr32BitsNoMap = 2,
Addr39Bits = 3,
}
}

View file

@ -58,11 +58,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
public ulong AslrRegionStart { get; private set; } public ulong AslrRegionStart { get; private set; }
public ulong AslrRegionEnd { get; private set; } public ulong AslrRegionEnd { get; private set; }
#pragma warning disable IDE0052 // Remove unread private member
private ulong _heapCapacity; private ulong _heapCapacity;
#pragma warning restore IDE0052
public ulong PhysicalMemoryUsage { get; private set; } public ulong PhysicalMemoryUsage { get; private set; }
public ulong AliasRegionExtraSize { get; private set; }
private readonly KMemoryBlockManager _blockManager; private readonly KMemoryBlockManager _blockManager;
@ -98,30 +97,21 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
_reservedAddressSpaceSize = reservedAddressSpaceSize; _reservedAddressSpaceSize = reservedAddressSpaceSize;
} }
private static readonly int[] _addrSpaceSizes = { 32, 36, 32, 39 };
public Result InitializeForProcess( public Result InitializeForProcess(
AddressSpaceType addrSpaceType, ProcessCreationFlags flags,
bool aslrEnabled,
bool fromBack, bool fromBack,
MemoryRegion memRegion, MemoryRegion memRegion,
ulong address, ulong address,
ulong size, ulong size,
KMemoryBlockSlabManager slabManager) KMemoryBlockSlabManager slabManager)
{ {
if ((uint)addrSpaceType > (uint)AddressSpaceType.Addr39Bits)
{
throw new ArgumentException($"AddressSpaceType bigger than {(uint)AddressSpaceType.Addr39Bits}: {(uint)addrSpaceType}", nameof(addrSpaceType));
}
_contextId = Context.ContextIdManager.GetId(); _contextId = Context.ContextIdManager.GetId();
ulong addrSpaceBase = 0; ulong addrSpaceBase = 0;
ulong addrSpaceSize = 1UL << _addrSpaceSizes[(int)addrSpaceType]; ulong addrSpaceSize = 1UL << GetAddressSpaceWidth(flags);
Result result = CreateUserAddressSpace( Result result = CreateUserAddressSpace(
addrSpaceType, flags,
aslrEnabled,
fromBack, fromBack,
addrSpaceBase, addrSpaceBase,
addrSpaceSize, addrSpaceSize,
@ -138,6 +128,22 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
return result; return result;
} }
private static int GetAddressSpaceWidth(ProcessCreationFlags flags)
{
switch (flags & ProcessCreationFlags.AddressSpaceMask)
{
case ProcessCreationFlags.AddressSpace32Bit:
case ProcessCreationFlags.AddressSpace32BitWithoutAlias:
return 32;
case ProcessCreationFlags.AddressSpace64BitDeprecated:
return 36;
case ProcessCreationFlags.AddressSpace64Bit:
return 39;
}
throw new ArgumentException($"Invalid process flags {flags}", nameof(flags));
}
private struct Region private struct Region
{ {
public ulong Start; public ulong Start;
@ -147,8 +153,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
} }
private Result CreateUserAddressSpace( private Result CreateUserAddressSpace(
AddressSpaceType addrSpaceType, ProcessCreationFlags flags,
bool aslrEnabled,
bool fromBack, bool fromBack,
ulong addrSpaceStart, ulong addrSpaceStart,
ulong addrSpaceEnd, ulong addrSpaceEnd,
@ -168,9 +173,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
ulong stackAndTlsIoStart; ulong stackAndTlsIoStart;
ulong stackAndTlsIoEnd; ulong stackAndTlsIoEnd;
switch (addrSpaceType) AliasRegionExtraSize = 0;
switch (flags & ProcessCreationFlags.AddressSpaceMask)
{ {
case AddressSpaceType.Addr32Bits: case ProcessCreationFlags.AddressSpace32Bit:
aliasRegion.Size = 0x40000000; aliasRegion.Size = 0x40000000;
heapRegion.Size = 0x40000000; heapRegion.Size = 0x40000000;
stackRegion.Size = 0; stackRegion.Size = 0;
@ -183,7 +190,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
stackAndTlsIoEnd = 0x40000000; stackAndTlsIoEnd = 0x40000000;
break; break;
case AddressSpaceType.Addr36Bits: case ProcessCreationFlags.AddressSpace64BitDeprecated:
aliasRegion.Size = 0x180000000; aliasRegion.Size = 0x180000000;
heapRegion.Size = 0x180000000; heapRegion.Size = 0x180000000;
stackRegion.Size = 0; stackRegion.Size = 0;
@ -196,7 +203,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
stackAndTlsIoEnd = 0x80000000; stackAndTlsIoEnd = 0x80000000;
break; break;
case AddressSpaceType.Addr32BitsNoMap: case ProcessCreationFlags.AddressSpace32BitWithoutAlias:
aliasRegion.Size = 0; aliasRegion.Size = 0;
heapRegion.Size = 0x80000000; heapRegion.Size = 0x80000000;
stackRegion.Size = 0; stackRegion.Size = 0;
@ -209,7 +216,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
stackAndTlsIoEnd = 0x40000000; stackAndTlsIoEnd = 0x40000000;
break; break;
case AddressSpaceType.Addr39Bits: case ProcessCreationFlags.AddressSpace64Bit:
if (_reservedAddressSpaceSize < addrSpaceEnd) if (_reservedAddressSpaceSize < addrSpaceEnd)
{ {
int addressSpaceWidth = (int)ulong.Log2(_reservedAddressSpaceSize); int addressSpaceWidth = (int)ulong.Log2(_reservedAddressSpaceSize);
@ -218,8 +225,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
heapRegion.Size = 0x180000000; heapRegion.Size = 0x180000000;
stackRegion.Size = 1UL << (addressSpaceWidth - 8); stackRegion.Size = 1UL << (addressSpaceWidth - 8);
tlsIoRegion.Size = 1UL << (addressSpaceWidth - 3); tlsIoRegion.Size = 1UL << (addressSpaceWidth - 3);
CodeRegionStart = BitUtils.AlignDown<ulong>(address, RegionAlignment); CodeRegionStart = BitUtils.AlignDown(address, RegionAlignment);
codeRegionSize = BitUtils.AlignUp<ulong>(endAddr, RegionAlignment) - CodeRegionStart; codeRegionSize = BitUtils.AlignUp(endAddr, RegionAlignment) - CodeRegionStart;
stackAndTlsIoStart = 0; stackAndTlsIoStart = 0;
stackAndTlsIoEnd = 0; stackAndTlsIoEnd = 0;
AslrRegionStart = 0x8000000; AslrRegionStart = 0x8000000;
@ -239,9 +246,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
stackAndTlsIoStart = 0; stackAndTlsIoStart = 0;
stackAndTlsIoEnd = 0; stackAndTlsIoEnd = 0;
} }
if (flags.HasFlag(ProcessCreationFlags.EnableAliasRegionExtraSize))
{
AliasRegionExtraSize = addrSpaceEnd / 8;
aliasRegion.Size += AliasRegionExtraSize;
}
break; break;
default: default:
throw new ArgumentException($"AddressSpaceType bigger than {(uint)AddressSpaceType.Addr39Bits}: {(uint)addrSpaceType}", nameof(addrSpaceType)); throw new ArgumentException($"Invalid process flags {flags}", nameof(flags));
} }
CodeRegionEnd = CodeRegionStart + codeRegionSize; CodeRegionEnd = CodeRegionStart + codeRegionSize;
@ -266,6 +280,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
ulong aslrMaxOffset = mapAvailableSize - mapTotalSize; ulong aslrMaxOffset = mapAvailableSize - mapTotalSize;
bool aslrEnabled = flags.HasFlag(ProcessCreationFlags.EnableAslr);
_aslrEnabled = aslrEnabled; _aslrEnabled = aslrEnabled;
AddrSpaceStart = addrSpaceStart; AddrSpaceStart = addrSpaceStart;
@ -725,7 +741,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
{ {
address = 0; address = 0;
if (size > HeapRegionEnd - HeapRegionStart) if (size > HeapRegionEnd - HeapRegionStart || size > _heapCapacity)
{ {
return KernelResult.OutOfMemory; return KernelResult.OutOfMemory;
} }

View file

@ -126,8 +126,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
_contextFactory = contextFactory ?? new ProcessContextFactory(); _contextFactory = contextFactory ?? new ProcessContextFactory();
_customThreadStart = customThreadStart; _customThreadStart = customThreadStart;
AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift);
Pid = KernelContext.NewKipId(); Pid = KernelContext.NewKipId();
if (Pid == 0 || Pid >= KernelConstants.InitialProcessId) if (Pid == 0 || Pid >= KernelConstants.InitialProcessId)
@ -137,8 +135,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
InitializeMemoryManager(creationInfo.Flags); InitializeMemoryManager(creationInfo.Flags);
bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr);
ulong codeAddress = creationInfo.CodeAddress; ulong codeAddress = creationInfo.CodeAddress;
ulong codeSize = (ulong)creationInfo.CodePagesCount * KPageTableBase.PageSize; ulong codeSize = (ulong)creationInfo.CodePagesCount * KPageTableBase.PageSize;
@ -148,9 +144,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
: KernelContext.SmallMemoryBlockSlabManager; : KernelContext.SmallMemoryBlockSlabManager;
Result result = MemoryManager.InitializeForProcess( Result result = MemoryManager.InitializeForProcess(
addrSpaceType, creationInfo.Flags,
aslrEnabled, !creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr),
!aslrEnabled,
memRegion, memRegion,
codeAddress, codeAddress,
codeSize, codeSize,
@ -234,8 +229,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
: KernelContext.SmallMemoryBlockSlabManager; : KernelContext.SmallMemoryBlockSlabManager;
} }
AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift);
Pid = KernelContext.NewProcessId(); Pid = KernelContext.NewProcessId();
if (Pid == ulong.MaxValue || Pid < KernelConstants.InitialProcessId) if (Pid == ulong.MaxValue || Pid < KernelConstants.InitialProcessId)
@ -245,16 +238,13 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
InitializeMemoryManager(creationInfo.Flags); InitializeMemoryManager(creationInfo.Flags);
bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr);
ulong codeAddress = creationInfo.CodeAddress; ulong codeAddress = creationInfo.CodeAddress;
ulong codeSize = codePagesCount * KPageTableBase.PageSize; ulong codeSize = codePagesCount * KPageTableBase.PageSize;
Result result = MemoryManager.InitializeForProcess( Result result = MemoryManager.InitializeForProcess(
addrSpaceType, creationInfo.Flags,
aslrEnabled, !creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr),
!aslrEnabled,
memRegion, memRegion,
codeAddress, codeAddress,
codeSize, codeSize,

View file

@ -29,6 +29,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
PoolPartitionMask = 0xf << PoolPartitionShift, PoolPartitionMask = 0xf << PoolPartitionShift,
OptimizeMemoryAllocation = 1 << 11, OptimizeMemoryAllocation = 1 << 11,
DisableDeviceAddressSpaceMerge = 1 << 12,
EnableAliasRegionExtraSize = 1 << 13,
All = All =
Is64Bit | Is64Bit |
@ -38,6 +40,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
IsApplication | IsApplication |
DeprecatedUseSecureMemory | DeprecatedUseSecureMemory |
PoolPartitionMask | PoolPartitionMask |
OptimizeMemoryAllocation, OptimizeMemoryAllocation |
DisableDeviceAddressSpaceMerge |
EnableAliasRegionExtraSize,
} }
} }

View file

@ -21,14 +21,17 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
SystemResourceSizeTotal, SystemResourceSizeTotal,
SystemResourceSizeUsed, SystemResourceSizeUsed,
ProgramId, ProgramId,
// NOTE: Added in 4.0.0, removed in 5.0.0. InitialProcessIdRange, // NOTE: Added in 4.0.0, removed in 5.0.0.
InitialProcessIdRange,
UserExceptionContextAddress, UserExceptionContextAddress,
TotalNonSystemMemorySize, TotalNonSystemMemorySize,
UsedNonSystemMemorySize, UsedNonSystemMemorySize,
IsApplication, IsApplication,
FreeThreadCount, FreeThreadCount,
ThreadTickCount, ThreadTickCount,
IsSvcPermitted,
IoRegionHint,
AliasRegionExtraSize,
MesosphereCurrentProcess = 65001, MesosphereCurrentProcess = 65001,
} }
} }

View file

@ -84,6 +84,17 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
return KernelResult.InvalidSize; return KernelResult.InvalidSize;
} }
if (info.Flags.HasFlag(ProcessCreationFlags.EnableAliasRegionExtraSize))
{
if ((info.Flags & ProcessCreationFlags.AddressSpaceMask) != ProcessCreationFlags.AddressSpace64Bit ||
info.SystemResourcePagesCount <= 0)
{
return KernelResult.InvalidState;
}
// TODO: Check that we are in debug mode.
}
if (info.Flags.HasFlag(ProcessCreationFlags.OptimizeMemoryAllocation) && if (info.Flags.HasFlag(ProcessCreationFlags.OptimizeMemoryAllocation) &&
!info.Flags.HasFlag(ProcessCreationFlags.IsApplication)) !info.Flags.HasFlag(ProcessCreationFlags.IsApplication))
{ {
@ -1978,6 +1989,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
case InfoType.UsedNonSystemMemorySize: case InfoType.UsedNonSystemMemorySize:
case InfoType.IsApplication: case InfoType.IsApplication:
case InfoType.FreeThreadCount: case InfoType.FreeThreadCount:
case InfoType.AliasRegionExtraSize:
{ {
if (subId != 0) if (subId != 0)
{ {
@ -2006,22 +2018,19 @@ 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:
value = process.GetMemoryCapacity(); value = process.GetMemoryCapacity();
break; break;
case InfoType.UsedMemorySize: case InfoType.UsedMemorySize:
value = process.GetMemoryUsage(); value = process.GetMemoryUsage();
break; break;
@ -2029,7 +2038,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
case InfoType.AslrRegionAddress: case InfoType.AslrRegionAddress:
value = process.MemoryManager.GetAddrSpaceBaseAddr(); value = process.MemoryManager.GetAddrSpaceBaseAddr();
break; break;
case InfoType.AslrRegionSize: case InfoType.AslrRegionSize:
value = process.MemoryManager.GetAddrSpaceSize(); value = process.MemoryManager.GetAddrSpaceSize();
break; break;
@ -2038,20 +2046,17 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
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:
value = process.PersonalMmHeapPagesCount * KPageTableBase.PageSize; value = process.PersonalMmHeapPagesCount * KPageTableBase.PageSize;
break; break;
case InfoType.SystemResourceSizeUsed: case InfoType.SystemResourceSizeUsed:
if (process.PersonalMmHeapPagesCount != 0) if (process.PersonalMmHeapPagesCount != 0)
{ {
value = process.MemoryManager.GetMmUsedPages() * KPageTableBase.PageSize; value = process.MemoryManager.GetMmUsedPages() * KPageTableBase.PageSize;
} }
break; break;
case InfoType.ProgramId: case InfoType.ProgramId:
@ -2065,7 +2070,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
case InfoType.TotalNonSystemMemorySize: case InfoType.TotalNonSystemMemorySize:
value = process.GetMemoryCapacityWithoutPersonalMmHeap(); value = process.GetMemoryCapacityWithoutPersonalMmHeap();
break; break;
case InfoType.UsedNonSystemMemorySize: case InfoType.UsedNonSystemMemorySize:
value = process.GetMemoryUsageWithoutPersonalMmHeap(); value = process.GetMemoryUsageWithoutPersonalMmHeap();
break; break;
@ -2084,10 +2088,12 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{ {
value = 0; value = 0;
} }
break;
case InfoType.AliasRegionExtraSize:
value = process.MemoryManager.AliasRegionExtraSize;
break; break;
} }
break; break;
} }
@ -2104,7 +2110,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
} }
value = KernelStatic.GetCurrentProcess().Debug ? 1UL : 0UL; value = KernelStatic.GetCurrentProcess().Debug ? 1UL : 0UL;
break; break;
} }
@ -2136,7 +2141,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
value = (uint)resLimHandle; value = (uint)resLimHandle;
} }
break; break;
} }
@ -2155,7 +2159,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
} }
value = (ulong)KTimeManager.ConvertHostTicksToTicks(_context.Schedulers[currentCore].TotalIdleTimeTicks); value = (ulong)KTimeManager.ConvertHostTicksToTicks(_context.Schedulers[currentCore].TotalIdleTimeTicks);
break; break;
} }
@ -2174,7 +2177,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
KProcess currentProcess = KernelStatic.GetCurrentProcess(); KProcess currentProcess = KernelStatic.GetCurrentProcess();
value = currentProcess.RandomEntropy[subId]; value = currentProcess.RandomEntropy[subId];
break; break;
} }
@ -2220,7 +2222,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
value = (ulong)KTimeManager.ConvertHostTicksToTicks(totalTimeRunning); value = (ulong)KTimeManager.ConvertHostTicksToTicks(totalTimeRunning);
} }
break; break;
} }
@ -2247,7 +2248,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
} }
value = (ulong)outHandle; value = (ulong)outHandle;
break; break;
} }