Allow to enable/disable memory checks even on release mode through the flag, return error for invalid addresses on SvcMap*Memory svcs, do not return error on SvcQueryMemory (instead, return reserved for the end of the address space), other minor tweaks
This commit is contained in:
@@ -52,6 +52,8 @@ namespace Ryujinx.Core.OsHle
|
||||
HidHandle = Handles.GenerateId(HidSharedMem);
|
||||
|
||||
FontHandle = Handles.GenerateId(new HSharedMem());
|
||||
|
||||
HidSharedMem.AddVirtualPosition(0);
|
||||
}
|
||||
|
||||
public void LoadCart(string ExeFsDir, string RomFsFile = null)
|
||||
|
@@ -217,16 +217,26 @@ namespace Ryujinx.Core.OsHle.Ipc
|
||||
|
||||
public long GetSendBuffPtr()
|
||||
{
|
||||
if (SendBuff.Count > 0 && SendBuff[0].Position != 0)
|
||||
if (SendBuff.Count > 0 && SendBuff[0].Size != 0)
|
||||
{
|
||||
return SendBuff[0].Position;
|
||||
}
|
||||
|
||||
if (PtrBuff.Count > 0 && PtrBuff[0].Position != 0)
|
||||
if (PtrBuff.Count > 0 && PtrBuff[0].Size != 0)
|
||||
{
|
||||
return PtrBuff[0].Position;
|
||||
}
|
||||
|
||||
if (ReceiveBuff.Count > 0 && ReceiveBuff[0].Size != 0)
|
||||
{
|
||||
return ReceiveBuff[0].Position;
|
||||
}
|
||||
|
||||
if (RecvListBuff.Count > 0 && RecvListBuff[0].Size != 0)
|
||||
{
|
||||
return RecvListBuff[0].Position;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@@ -81,7 +81,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
FileDesc FdData = Context.Ns.Os.Fds.GetData<FileDesc>(Fd);
|
||||
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
Context.ResponseData.Write(0);
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvGpuAsIoctlBindChannel(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
int Fd = Context.Memory.ReadInt32(Position);
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvGpuAsIoctlAllocSpace(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvGpuAsIoctlMapBufferEx(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvGpuAsIoctlGetVaRegions(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
MemWriter Writer = new MemWriter(Context.Memory, Position);
|
||||
@@ -237,7 +237,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvGpuAsIoctlInitializeEx(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvHostIoctlCtrlGetConfig(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
MemWriter Writer = new MemWriter(Context.Memory, Position + 0x82);
|
||||
@@ -269,7 +269,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvHostIoctlCtrlEventWait(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
|
||||
@@ -285,7 +285,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvGpuIoctlZcullGetCtxSize(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
Context.Memory.WriteInt32(Position, 1);
|
||||
|
||||
@@ -294,7 +294,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvGpuIoctlZcullGetInfo(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemWriter Writer = new MemWriter(Context.Memory, Position);
|
||||
|
||||
@@ -314,7 +314,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvGpuIoctlGetCharacteristics(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
MemWriter Writer = new MemWriter(Context.Memory, Position);
|
||||
@@ -376,7 +376,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvGpuIoctlGetTpcMasks(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
|
||||
@@ -390,7 +390,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvGpuIoctlZbcGetActiveSlotMask(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
Context.Memory.WriteInt32(Position + 0, 7);
|
||||
Context.Memory.WriteInt32(Position + 4, 1);
|
||||
@@ -400,14 +400,14 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvMapIoctlChannelSetUserData(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static long NvMapIoctlChannelSetNvMap(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
int Fd = Context.Memory.ReadInt32(Position);
|
||||
|
||||
@@ -416,7 +416,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvMapIoctlChannelSubmitGpFifo(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
MemWriter Writer = new MemWriter(Context.Memory, Position + 0x10);
|
||||
@@ -455,7 +455,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvMapIoctlChannelAllocObjCtx(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
int ClassNum = Context.Memory.ReadInt32(Position + 0);
|
||||
int Flags = Context.Memory.ReadInt32(Position + 4);
|
||||
@@ -467,7 +467,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvMapIoctlChannelZcullBind(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
|
||||
@@ -480,7 +480,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvMapIoctlChannelSetErrorNotifier(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
|
||||
@@ -494,7 +494,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvMapIoctlChannelSetPriority(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
int Priority = Context.Memory.ReadInt32(Position);
|
||||
|
||||
@@ -503,7 +503,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices
|
||||
|
||||
private static long NvMapIoctlChannelAllocGpFifoEx2(ServiceCtx Context)
|
||||
{
|
||||
long Position = Context.Request.PtrBuff[0].Position;
|
||||
long Position = Context.Request.GetSendBuffPtr();
|
||||
|
||||
MemReader Reader = new MemReader(Context.Memory, Position);
|
||||
MemWriter Writer = new MemWriter(Context.Memory, Position + 0xc);
|
||||
|
@@ -55,6 +55,24 @@ namespace Ryujinx.Core.OsHle.Svc
|
||||
long Src = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
|
||||
if (!IsValidPosition(Src))
|
||||
{
|
||||
Logging.Warn($"Tried to map Memory at invalid src address {Src:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsValidMapPosition(Dst))
|
||||
{
|
||||
Logging.Warn($"Tried to map Memory at invalid dst address {Dst:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AMemoryMapInfo SrcInfo = Memory.Manager.GetMapInfo(Src);
|
||||
|
||||
Memory.Manager.Map(Dst, Size, (int)MemoryType.MappedMemory, SrcInfo.Perm);
|
||||
@@ -72,6 +90,24 @@ namespace Ryujinx.Core.OsHle.Svc
|
||||
long Src = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
|
||||
if (!IsValidPosition(Src))
|
||||
{
|
||||
Logging.Warn($"Tried to unmap Memory at invalid src address {Src:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsValidMapPosition(Dst))
|
||||
{
|
||||
Logging.Warn($"Tried to unmap Memory at invalid dst address {Dst:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AMemoryMapInfo DstInfo = Memory.Manager.GetMapInfo(Dst);
|
||||
|
||||
Memory.Manager.Unmap(Dst, Size, (int)MemoryType.MappedMemory);
|
||||
@@ -92,9 +128,11 @@ namespace Ryujinx.Core.OsHle.Svc
|
||||
|
||||
if (MapInfo == null)
|
||||
{
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange);
|
||||
long AddrSpaceEnd = MemoryRegions.AddrSpaceStart + MemoryRegions.AddrSpaceSize;
|
||||
|
||||
return;
|
||||
long ReservedSize = (long)(ulong.MaxValue - (ulong)AddrSpaceEnd) + 1;
|
||||
|
||||
MapInfo = new AMemoryMapInfo(AddrSpaceEnd, ReservedSize, (int)MemoryType.Reserved, 0, AMemoryPerm.None);
|
||||
}
|
||||
|
||||
Memory.WriteInt64(InfoPtr + 0x00, MapInfo.Position);
|
||||
@@ -118,15 +156,26 @@ namespace Ryujinx.Core.OsHle.Svc
|
||||
long Size = (long)ThreadState.X2;
|
||||
int Perm = (int)ThreadState.X3;
|
||||
|
||||
if (!IsValidPosition(Src))
|
||||
{
|
||||
Logging.Warn($"Tried to map SharedMemory at invalid address {Src:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HSharedMem SharedMem = Ns.Os.Handles.GetData<HSharedMem>(Handle);
|
||||
|
||||
if (SharedMem != null)
|
||||
{
|
||||
Memory.Manager.Map(Src, Size, (int)MemoryType.SharedMemory, AMemoryPerm.Write);
|
||||
|
||||
AMemoryHelper.FillWithZeros(Memory, Src, (int)Size);
|
||||
|
||||
SharedMem.AddVirtualPosition(Src);
|
||||
Memory.Manager.Reprotect(Src, Size, (AMemoryPerm)Perm);
|
||||
|
||||
Memory.Manager.Map(Src, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm);
|
||||
SharedMem.AddVirtualPosition(Src);
|
||||
|
||||
ThreadState.X0 = 0;
|
||||
}
|
||||
@@ -136,14 +185,25 @@ namespace Ryujinx.Core.OsHle.Svc
|
||||
|
||||
private void SvcUnmapSharedMemory(AThreadState ThreadState)
|
||||
{
|
||||
int Handle = (int)ThreadState.X0;
|
||||
long Position = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
int Handle = (int)ThreadState.X0;
|
||||
long Src = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
|
||||
if (!IsValidPosition(Src))
|
||||
{
|
||||
Logging.Warn($"Tried to unmap SharedMemory at invalid address {Src:x16}!");
|
||||
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HSharedMem HndData = Ns.Os.Handles.GetData<HSharedMem>(Handle);
|
||||
|
||||
if (HndData != null)
|
||||
{
|
||||
Memory.Manager.Unmap(Src, Size, (int)MemoryType.SharedMemory);
|
||||
|
||||
ThreadState.X0 = 0;
|
||||
}
|
||||
|
||||
@@ -152,20 +212,41 @@ namespace Ryujinx.Core.OsHle.Svc
|
||||
|
||||
private void SvcCreateTransferMemory(AThreadState ThreadState)
|
||||
{
|
||||
long Position = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
int Perm = (int)ThreadState.X3;
|
||||
long Src = (long)ThreadState.X1;
|
||||
long Size = (long)ThreadState.X2;
|
||||
int Perm = (int)ThreadState.X3;
|
||||
|
||||
AMemoryMapInfo MapInfo = Memory.Manager.GetMapInfo(Position);
|
||||
if (!IsValidPosition(Src))
|
||||
{
|
||||
Logging.Warn($"Tried to create TransferMemory at invalid address {Src:x16}!");
|
||||
|
||||
Memory.Manager.Reprotect(Position, Size, (AMemoryPerm)Perm);
|
||||
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange);
|
||||
|
||||
HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Position, Size);
|
||||
return;
|
||||
}
|
||||
|
||||
AMemoryMapInfo MapInfo = Memory.Manager.GetMapInfo(Src);
|
||||
|
||||
Memory.Manager.Reprotect(Src, Size, (AMemoryPerm)Perm);
|
||||
|
||||
HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Src, Size);
|
||||
|
||||
int Handle = Ns.Os.Handles.GenerateId(HndData);
|
||||
|
||||
ThreadState.X1 = (ulong)Handle;
|
||||
ThreadState.X0 = 0;
|
||||
}
|
||||
|
||||
private static bool IsValidPosition(long Position)
|
||||
{
|
||||
return Position >= MemoryRegions.AddrSpaceStart &&
|
||||
Position < MemoryRegions.AddrSpaceStart + MemoryRegions.AddrSpaceSize;
|
||||
}
|
||||
|
||||
private static bool IsValidMapPosition(long Position)
|
||||
{
|
||||
return Position >= MemoryRegions.MapRegionAddress &&
|
||||
Position < MemoryRegions.MapRegionAddress + MemoryRegions.MapRegionSize;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user