Better process implementation (#491)
* Initial implementation of KProcess * Some improvements to the memory manager, implement back guest stack trace printing * Better GetInfo implementation, improve checking in some places with information from process capabilities * Allow the cpu to read/write from the correct memory locations for accesses crossing a page boundary * Change long -> ulong for address/size on memory related methods to avoid unnecessary casts * Attempt at implementing ldr:ro with new KProcess * Allow BSS with size 0 on ldr:ro * Add checking for memory block slab heap usage, return errors if full, exit gracefully * Use KMemoryBlockSize const from KMemoryManager * Allow all methods to read from non-contiguous locations * Fix for TransactParcelAuto * Address PR feedback, additionally fix some small issues related to the KIP loader and implement SVCs GetProcessId, GetProcessList, GetSystemInfo, CreatePort and ManageNamedPort * Fix wrong check for source pages count from page list on MapPhysicalMemory * Fix some issues with UnloadNro on ldr:ro
This commit is contained in:
parent
e7fe7d7247
commit
00579927e4
119 changed files with 7998 additions and 3232 deletions
|
@ -11,7 +11,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
{
|
||||
ulong Size = ThreadState.X1;
|
||||
|
||||
if ((Size & 0xFFFFFFFE001FFFFF) != 0)
|
||||
if ((Size & 0xfffffffe001fffff) != 0)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Heap size 0x{Size:x16} is not aligned!");
|
||||
|
||||
|
@ -20,24 +20,24 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
long Result = Process.MemoryManager.TrySetHeapSize((long)Size, out long Position);
|
||||
KernelResult Result = Process.MemoryManager.SetHeapSize(Size, out ulong Position);
|
||||
|
||||
ThreadState.X0 = (ulong)Result;
|
||||
|
||||
if (Result == 0)
|
||||
if (Result == KernelResult.Success)
|
||||
{
|
||||
ThreadState.X1 = (ulong)Position;
|
||||
ThreadState.X1 = Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{Result}\".");
|
||||
}
|
||||
}
|
||||
|
||||
private void SvcSetMemoryAttribute(CpuThreadState ThreadState)
|
||||
{
|
||||
long Position = (long)ThreadState.X0;
|
||||
long Size = (long)ThreadState.X1;
|
||||
ulong Position = ThreadState.X0;
|
||||
ulong Size = ThreadState.X1;
|
||||
|
||||
if (!PageAligned(Position))
|
||||
{
|
||||
|
@ -72,19 +72,19 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
long Result = Process.MemoryManager.SetMemoryAttribute(
|
||||
KernelResult Result = Process.MemoryManager.SetMemoryAttribute(
|
||||
Position,
|
||||
Size,
|
||||
AttributeMask,
|
||||
AttributeValue);
|
||||
|
||||
if (Result != 0)
|
||||
if (Result != KernelResult.Success)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{Result}\".");
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory.StopObservingRegion(Position, Size);
|
||||
Memory.StopObservingRegion((long)Position, (long)Size);
|
||||
}
|
||||
|
||||
ThreadState.X0 = (ulong)Result;
|
||||
|
@ -92,9 +92,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
|
||||
private void SvcMapMemory(CpuThreadState ThreadState)
|
||||
{
|
||||
long Dst = (long)ThreadState.X0;
|
||||
long Src = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
ulong Dst = ThreadState.X0;
|
||||
ulong Src = ThreadState.X1;
|
||||
ulong Size = ThreadState.X2;
|
||||
|
||||
if (!PageAligned(Src | Dst))
|
||||
{
|
||||
|
@ -114,7 +114,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if ((ulong)(Src + Size) <= (ulong)Src || (ulong)(Dst + Size) <= (ulong)Dst)
|
||||
if (Src + Size <= Src || Dst + Size <= Dst)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, "Addresses outside of range!");
|
||||
|
||||
|
@ -123,7 +123,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if (!InsideAddrSpace(Src, Size))
|
||||
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
|
||||
|
||||
if (!CurrentProcess.MemoryManager.InsideAddrSpace(Src, Size))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Src address 0x{Src:x16} out of range!");
|
||||
|
||||
|
@ -132,7 +134,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if (!InsideNewMapRegion(Dst, Size))
|
||||
if (CurrentProcess.MemoryManager.OutsideStackRegion(Dst, Size) ||
|
||||
CurrentProcess.MemoryManager.InsideHeapRegion (Dst, Size) ||
|
||||
CurrentProcess.MemoryManager.InsideAliasRegion (Dst, Size))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Dst address 0x{Dst:x16} out of range!");
|
||||
|
||||
|
@ -141,9 +145,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
long Result = Process.MemoryManager.Map(Src, Dst, Size);
|
||||
KernelResult Result = Process.MemoryManager.Map(Dst, Src, Size);
|
||||
|
||||
if (Result != 0)
|
||||
if (Result != KernelResult.Success)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!");
|
||||
}
|
||||
|
@ -153,9 +157,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
|
||||
private void SvcUnmapMemory(CpuThreadState ThreadState)
|
||||
{
|
||||
long Dst = (long)ThreadState.X0;
|
||||
long Src = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
ulong Dst = ThreadState.X0;
|
||||
ulong Src = ThreadState.X1;
|
||||
ulong Size = ThreadState.X2;
|
||||
|
||||
if (!PageAligned(Src | Dst))
|
||||
{
|
||||
|
@ -175,7 +179,7 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if ((ulong)(Src + Size) <= (ulong)Src || (ulong)(Dst + Size) <= (ulong)Dst)
|
||||
if (Src + Size <= Src || Dst + Size <= Dst)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, "Addresses outside of range!");
|
||||
|
||||
|
@ -184,7 +188,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if (!InsideAddrSpace(Src, Size))
|
||||
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
|
||||
|
||||
if (!CurrentProcess.MemoryManager.InsideAddrSpace(Src, Size))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Src address 0x{Src:x16} out of range!");
|
||||
|
||||
|
@ -193,7 +199,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if (!InsideNewMapRegion(Dst, Size))
|
||||
if (CurrentProcess.MemoryManager.OutsideStackRegion(Dst, Size) ||
|
||||
CurrentProcess.MemoryManager.InsideHeapRegion (Dst, Size) ||
|
||||
CurrentProcess.MemoryManager.InsideAliasRegion (Dst, Size))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Dst address 0x{Dst:x16} out of range!");
|
||||
|
||||
|
@ -202,9 +210,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
long Result = Process.MemoryManager.Unmap(Src, Dst, Size);
|
||||
KernelResult Result = Process.MemoryManager.Unmap(Dst, Src, Size);
|
||||
|
||||
if (Result != 0)
|
||||
if (Result != KernelResult.Success)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!");
|
||||
}
|
||||
|
@ -214,19 +222,19 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
|
||||
private void SvcQueryMemory(CpuThreadState ThreadState)
|
||||
{
|
||||
long InfoPtr = (long)ThreadState.X0;
|
||||
long Position = (long)ThreadState.X2;
|
||||
long InfoPtr = (long)ThreadState.X0;
|
||||
ulong Position = ThreadState.X2;
|
||||
|
||||
KMemoryInfo BlkInfo = Process.MemoryManager.QueryMemory(Position);
|
||||
|
||||
Memory.WriteInt64(InfoPtr + 0x00, BlkInfo.Position);
|
||||
Memory.WriteInt64(InfoPtr + 0x08, BlkInfo.Size);
|
||||
Memory.WriteInt32(InfoPtr + 0x10, (int)BlkInfo.State & 0xff);
|
||||
Memory.WriteInt32(InfoPtr + 0x14, (int)BlkInfo.Attribute);
|
||||
Memory.WriteInt32(InfoPtr + 0x18, (int)BlkInfo.Permission);
|
||||
Memory.WriteInt32(InfoPtr + 0x1c, BlkInfo.IpcRefCount);
|
||||
Memory.WriteInt32(InfoPtr + 0x20, BlkInfo.DeviceRefCount);
|
||||
Memory.WriteInt32(InfoPtr + 0x24, 0);
|
||||
Memory.WriteUInt64(InfoPtr + 0x00, BlkInfo.Address);
|
||||
Memory.WriteUInt64(InfoPtr + 0x08, BlkInfo.Size);
|
||||
Memory.WriteInt32 (InfoPtr + 0x10, (int)BlkInfo.State & 0xff);
|
||||
Memory.WriteInt32 (InfoPtr + 0x14, (int)BlkInfo.Attribute);
|
||||
Memory.WriteInt32 (InfoPtr + 0x18, (int)BlkInfo.Permission);
|
||||
Memory.WriteInt32 (InfoPtr + 0x1c, BlkInfo.IpcRefCount);
|
||||
Memory.WriteInt32 (InfoPtr + 0x20, BlkInfo.DeviceRefCount);
|
||||
Memory.WriteInt32 (InfoPtr + 0x24, 0);
|
||||
|
||||
ThreadState.X0 = 0;
|
||||
ThreadState.X1 = 0;
|
||||
|
@ -234,13 +242,13 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
|
||||
private void SvcMapSharedMemory(CpuThreadState ThreadState)
|
||||
{
|
||||
int Handle = (int)ThreadState.X0;
|
||||
long Position = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
int Handle = (int)ThreadState.X0;
|
||||
ulong Address = ThreadState.X1;
|
||||
ulong Size = ThreadState.X2;
|
||||
|
||||
if (!PageAligned(Position))
|
||||
if (!PageAligned(Address))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
||||
|
||||
|
@ -256,9 +264,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if ((ulong)(Position + Size) <= (ulong)Position)
|
||||
if (Address + Size <= Address)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||
|
||||
|
@ -276,7 +284,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
KSharedMemory SharedMemory = Process.HandleTable.GetObject<KSharedMemory>(Handle);
|
||||
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
|
||||
|
||||
KSharedMemory SharedMemory = CurrentProcess.HandleTable.GetObject<KSharedMemory>(Handle);
|
||||
|
||||
if (SharedMemory == null)
|
||||
{
|
||||
|
@ -287,29 +297,27 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if (!InsideAddrSpace(Position, Size) || InsideMapRegion(Position, Size) || InsideHeapRegion(Position, Size))
|
||||
if (CurrentProcess.MemoryManager.IsInvalidRegion (Address, Size) ||
|
||||
CurrentProcess.MemoryManager.InsideHeapRegion (Address, Size) ||
|
||||
CurrentProcess.MemoryManager.InsideAliasRegion(Address, Size))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} out of range!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} out of range!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (SharedMemory.Size != Size)
|
||||
KernelResult Result = SharedMemory.MapIntoProcess(
|
||||
CurrentProcess.MemoryManager,
|
||||
Address,
|
||||
Size,
|
||||
CurrentProcess,
|
||||
Permission);
|
||||
|
||||
if (Result != KernelResult.Success)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Size 0x{Size:x16} does not match shared memory size 0x{SharedMemory.Size:16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidSize);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
long Result = Process.MemoryManager.MapSharedMemory(SharedMemory, Permission, Position);
|
||||
|
||||
if (Result != 0)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{Result}\".");
|
||||
}
|
||||
|
||||
ThreadState.X0 = (ulong)Result;
|
||||
|
@ -317,13 +325,13 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
|
||||
private void SvcUnmapSharedMemory(CpuThreadState ThreadState)
|
||||
{
|
||||
int Handle = (int)ThreadState.X0;
|
||||
long Position = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
int Handle = (int)ThreadState.X0;
|
||||
ulong Address = ThreadState.X1;
|
||||
ulong Size = ThreadState.X2;
|
||||
|
||||
if (!PageAligned(Position))
|
||||
if (!PageAligned(Address))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
||||
|
||||
|
@ -339,16 +347,18 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if ((ulong)(Position + Size) <= (ulong)Position)
|
||||
if (Address + Size <= Address)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
KSharedMemory SharedMemory = Process.HandleTable.GetObject<KSharedMemory>(Handle);
|
||||
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
|
||||
|
||||
KSharedMemory SharedMemory = CurrentProcess.HandleTable.GetObject<KSharedMemory>(Handle);
|
||||
|
||||
if (SharedMemory == null)
|
||||
{
|
||||
|
@ -359,20 +369,26 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if (!InsideAddrSpace(Position, Size) || InsideMapRegion(Position, Size) || InsideHeapRegion(Position, Size))
|
||||
if (CurrentProcess.MemoryManager.IsInvalidRegion (Address, Size) ||
|
||||
CurrentProcess.MemoryManager.InsideHeapRegion (Address, Size) ||
|
||||
CurrentProcess.MemoryManager.InsideAliasRegion(Address, Size))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} out of range!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} out of range!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
long Result = Process.MemoryManager.UnmapSharedMemory(Position, Size);
|
||||
KernelResult Result = SharedMemory.UnmapFromProcess(
|
||||
CurrentProcess.MemoryManager,
|
||||
Address,
|
||||
Size,
|
||||
CurrentProcess);
|
||||
|
||||
if (Result != 0)
|
||||
if (Result != KernelResult.Success)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error \"{Result}\".");
|
||||
}
|
||||
|
||||
ThreadState.X0 = (ulong)Result;
|
||||
|
@ -380,12 +396,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
|
||||
private void SvcCreateTransferMemory(CpuThreadState ThreadState)
|
||||
{
|
||||
long Position = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
ulong Address = ThreadState.X1;
|
||||
ulong Size = ThreadState.X2;
|
||||
|
||||
if (!PageAligned(Position))
|
||||
if (!PageAligned(Address))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
||||
|
||||
|
@ -401,9 +417,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if ((ulong)(Position + Size) <= (ulong)Position)
|
||||
if (Address + Size <= Address)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||
|
||||
|
@ -421,9 +437,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
Process.MemoryManager.ReserveTransferMemory(Position, Size, Permission);
|
||||
Process.MemoryManager.ReserveTransferMemory(Address, Size, Permission);
|
||||
|
||||
KTransferMemory TransferMemory = new KTransferMemory(Position, Size);
|
||||
KTransferMemory TransferMemory = new KTransferMemory(Address, Size);
|
||||
|
||||
KernelResult Result = Process.HandleTable.GenerateHandle(TransferMemory, out int Handle);
|
||||
|
||||
|
@ -433,12 +449,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
|
||||
private void SvcMapPhysicalMemory(CpuThreadState ThreadState)
|
||||
{
|
||||
long Position = (long)ThreadState.X0;
|
||||
long Size = (long)ThreadState.X1;
|
||||
ulong Address = ThreadState.X0;
|
||||
ulong Size = ThreadState.X1;
|
||||
|
||||
if (!PageAligned(Position))
|
||||
if (!PageAligned(Address))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
||||
|
||||
|
@ -454,27 +470,39 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if ((ulong)(Position + Size) <= (ulong)Position)
|
||||
if (Address + Size <= Address)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InsideAddrSpace(Position, Size))
|
||||
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
|
||||
|
||||
if ((CurrentProcess.PersonalMmHeapPagesCount & 0xfffffffffffff) == 0)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Position:x16}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"System resource size is zero.");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CurrentProcess.MemoryManager.InsideAddrSpace (Address, Size) ||
|
||||
CurrentProcess.MemoryManager.OutsideAliasRegion(Address, Size))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Address:x16}.");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
long Result = Process.MemoryManager.MapPhysicalMemory(Position, Size);
|
||||
KernelResult Result = Process.MemoryManager.MapPhysicalMemory(Address, Size);
|
||||
|
||||
if (Result != 0)
|
||||
if (Result != KernelResult.Success)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!");
|
||||
}
|
||||
|
@ -484,12 +512,12 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
|
||||
private void SvcUnmapPhysicalMemory(CpuThreadState ThreadState)
|
||||
{
|
||||
long Position = (long)ThreadState.X0;
|
||||
long Size = (long)ThreadState.X1;
|
||||
ulong Address = ThreadState.X0;
|
||||
ulong Size = ThreadState.X1;
|
||||
|
||||
if (!PageAligned(Position))
|
||||
if (!PageAligned(Address))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Position:x16} is not page aligned!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Address 0x{Address:x16} is not page aligned!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidAddress);
|
||||
|
||||
|
@ -505,27 +533,39 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
if ((ulong)(Position + Size) <= (ulong)Position)
|
||||
if (Address + Size <= Address)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Position:x16} / size 0x{Size:x16}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid region address 0x{Address:x16} / size 0x{Size:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InsideAddrSpace(Position, Size))
|
||||
KProcess CurrentProcess = System.Scheduler.GetCurrentProcess();
|
||||
|
||||
if ((CurrentProcess.PersonalMmHeapPagesCount & 0xfffffffffffff) == 0)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Position:x16}!");
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"System resource size is zero.");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidState);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CurrentProcess.MemoryManager.InsideAddrSpace (Address, Size) ||
|
||||
CurrentProcess.MemoryManager.OutsideAliasRegion(Address, Size))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Invalid address {Address:x16}.");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
long Result = Process.MemoryManager.UnmapPhysicalMemory(Position, Size);
|
||||
KernelResult Result = Process.MemoryManager.UnmapPhysicalMemory(Address, Size);
|
||||
|
||||
if (Result != 0)
|
||||
if (Result != KernelResult.Success)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.KernelSvc, $"Operation failed with error 0x{Result:x}!");
|
||||
}
|
||||
|
@ -533,45 +573,9 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
ThreadState.X0 = (ulong)Result;
|
||||
}
|
||||
|
||||
private static bool PageAligned(long Position)
|
||||
private static bool PageAligned(ulong Position)
|
||||
{
|
||||
return (Position & (KMemoryManager.PageSize - 1)) == 0;
|
||||
}
|
||||
|
||||
private bool InsideAddrSpace(long Position, long Size)
|
||||
{
|
||||
ulong Start = (ulong)Position;
|
||||
ulong End = (ulong)Size + Start;
|
||||
|
||||
return Start >= (ulong)Process.MemoryManager.AddrSpaceStart &&
|
||||
End < (ulong)Process.MemoryManager.AddrSpaceEnd;
|
||||
}
|
||||
|
||||
private bool InsideMapRegion(long Position, long Size)
|
||||
{
|
||||
ulong Start = (ulong)Position;
|
||||
ulong End = (ulong)Size + Start;
|
||||
|
||||
return Start >= (ulong)Process.MemoryManager.MapRegionStart &&
|
||||
End < (ulong)Process.MemoryManager.MapRegionEnd;
|
||||
}
|
||||
|
||||
private bool InsideHeapRegion(long Position, long Size)
|
||||
{
|
||||
ulong Start = (ulong)Position;
|
||||
ulong End = (ulong)Size + Start;
|
||||
|
||||
return Start >= (ulong)Process.MemoryManager.HeapRegionStart &&
|
||||
End < (ulong)Process.MemoryManager.HeapRegionEnd;
|
||||
}
|
||||
|
||||
private bool InsideNewMapRegion(long Position, long Size)
|
||||
{
|
||||
ulong Start = (ulong)Position;
|
||||
ulong End = (ulong)Size + Start;
|
||||
|
||||
return Start >= (ulong)Process.MemoryManager.NewMapRegionStart &&
|
||||
End < (ulong)Process.MemoryManager.NewMapRegionEnd;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue