From 89e703302b9a3d4d8969e7bfc5c0280032bae30c Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sat, 29 Dec 2018 03:13:04 -0300 Subject: [PATCH] Misc fixes and improvements on new IPC methods --- Ryujinx.HLE/DeviceMemory.cs | 25 ++ Ryujinx.HLE/HOS/Kernel/Ipc/ChannelState.cs | 10 + Ryujinx.HLE/HOS/Kernel/Ipc/KClientPort.cs | 9 +- Ryujinx.HLE/HOS/Kernel/Ipc/KClientSession.cs | 5 +- Ryujinx.HLE/HOS/Kernel/Ipc/KPort.cs | 19 +- Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs | 11 +- Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs | 248 ++++++++++-------- Ryujinx.HLE/HOS/Kernel/Ipc/KSession.cs | 18 ++ Ryujinx.HLE/HOS/Kernel/Ipc/KSessionRequest.cs | 9 +- .../HOS/Kernel/Memory/KMemoryManager.cs | 21 +- .../HOS/Kernel/SupervisorCall/SvcSystem.cs | 10 +- Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs | 10 +- 12 files changed, 239 insertions(+), 156 deletions(-) create mode 100644 Ryujinx.HLE/HOS/Kernel/Ipc/ChannelState.cs diff --git a/Ryujinx.HLE/DeviceMemory.cs b/Ryujinx.HLE/DeviceMemory.cs index fb4f4e03f2..310942b872 100644 --- a/Ryujinx.HLE/DeviceMemory.cs +++ b/Ryujinx.HLE/DeviceMemory.cs @@ -115,6 +115,16 @@ namespace Ryujinx.HLE public void Set(ulong address, byte value, ulong size) { + if (address + size < address) + { + throw new ArgumentOutOfRangeException(nameof(size)); + } + + if (address + size > RamSize) + { + throw new ArgumentOutOfRangeException(nameof(address)); + } + ulong size8 = size & ~7UL; ulong valueRep = (ulong)value * 0x0101010101010101; @@ -132,6 +142,21 @@ namespace Ryujinx.HLE public void Copy(ulong dst, ulong src, ulong size) { + if (dst + size < dst || src + size < src) + { + throw new ArgumentOutOfRangeException(nameof(size)); + } + + if (dst + size > RamSize) + { + throw new ArgumentOutOfRangeException(nameof(dst)); + } + + if (src + size > RamSize) + { + throw new ArgumentOutOfRangeException(nameof(src)); + } + ulong size8 = size & ~7UL; for (ulong offs = 0; offs < size8; offs += 8) diff --git a/Ryujinx.HLE/HOS/Kernel/Ipc/ChannelState.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/ChannelState.cs new file mode 100644 index 0000000000..4827384eba --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Ipc/ChannelState.cs @@ -0,0 +1,10 @@ +namespace Ryujinx.HLE.HOS.Kernel.Ipc +{ + enum ChannelState + { + NotInitialized, + Open, + ClientDisconnected, + ServerDisconnected + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Ipc/KClientPort.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KClientPort.cs index 375f050b64..d79b5d4ca6 100644 --- a/Ryujinx.HLE/HOS/Kernel/Ipc/KClientPort.cs +++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KClientPort.cs @@ -18,15 +18,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc //SM implementation to work with the new IPC system. public IpcService Service { get; set; } - public KClientPort(Horizon system) : base(system) - { - _countIncLock = new object(); - } - - public void Initialize(KPort parent, int maxSessions) + public KClientPort(Horizon system, KPort parent, int maxSessions) : base(system) { _maxSessions = maxSessions; _parent = parent; + + _countIncLock = new object(); } public KernelResult Connect(out KClientSession clientSession) diff --git a/Ryujinx.HLE/HOS/Kernel/Ipc/KClientSession.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KClientSession.cs index eaaf65805b..31c1e43e9b 100644 --- a/Ryujinx.HLE/HOS/Kernel/Ipc/KClientSession.cs +++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KClientSession.cs @@ -11,7 +11,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc private KSession _parent; - public int ResourceStatus { get; private set; } + public ChannelState State { get; set; } //TODO: Remove that, we need it for now to allow HLE //services implementation to work with the new IPC system. @@ -21,7 +21,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc { _parent = parent; - ResourceStatus = 1; + State = ChannelState.Open; } public KernelResult SendSyncRequest(ulong customCmdBuffAddr = 0, ulong customCmdBuffSize = 0) @@ -51,6 +51,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc protected override void Destroy() { + _parent.DisconnectClient(); _parent.DecrementReferenceCount(); } } diff --git a/Ryujinx.HLE/HOS/Kernel/Ipc/KPort.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KPort.cs index 1fc0c98e3b..3bdd11b5e0 100644 --- a/Ryujinx.HLE/HOS/Kernel/Ipc/KPort.cs +++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KPort.cs @@ -8,25 +8,20 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc public KClientPort ClientPort { get; } private long _nameAddress; - private int _resourceStatus; + + private ChannelState _state; public bool IsLight { get; private set; } - public KPort(Horizon system) : base(system) + public KPort(Horizon system, int maxSessions, bool isLight, long nameAddress) : base(system) { - ServerPort = new KServerPort(system); - ClientPort = new KClientPort(system); - } - - public void Initialize(int maxSessions, bool isLight, long nameAddress) - { - ServerPort.Initialize(this); - ClientPort.Initialize(this, maxSessions); + ServerPort = new KServerPort(system, this); + ClientPort = new KClientPort(system, this, maxSessions); IsLight = isLight; _nameAddress = nameAddress; - _resourceStatus = 1; + _state = ChannelState.Open; } public KernelResult EnqueueIncomingSession(KServerSession session) @@ -35,7 +30,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc System.CriticalSection.Enter(); - if (_resourceStatus == 1) + if (_state == ChannelState.Open) { ServerPort.EnqueueIncomingSession(session); diff --git a/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs index 2ec62871b1..fb46bdc62b 100644 --- a/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs +++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KServerPort.cs @@ -12,15 +12,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc public bool IsLight => _parent.IsLight; - public KServerPort(Horizon system) : base(system) - { - _incomingConnections = new LinkedList(); - _lightIncomingConnections = new LinkedList(); - } - - public void Initialize(KPort parent) + public KServerPort(Horizon system, KPort parent) : base(system) { _parent = parent; + + _incomingConnections = new LinkedList(); + _lightIncomingConnections = new LinkedList(); } public void EnqueueIncomingSession(KServerSession session) diff --git a/Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs index 4695498470..4f79e5b55e 100644 --- a/Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs +++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs @@ -173,20 +173,20 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc public KernelResult EnqueueRequest(KSessionRequest request) { - if (_parent.ClientSession.ResourceStatus != 1) + if (_parent.ClientSession.State != ChannelState.Open) { return KernelResult.PortRemoteClosed; } if (request.AsyncEvent == null) { - if (request.SenderThread.ShallBeTerminated || - request.SenderThread.SchedFlags == ThreadSchedState.TerminationPending) + if (request.ClientThread.ShallBeTerminated || + request.ClientThread.SchedFlags == ThreadSchedState.TerminationPending) { return KernelResult.ThreadTerminating; } - request.SenderThread.Reschedule(ThreadSchedState.Paused); + request.ClientThread.Reschedule(ThreadSchedState.Paused); } _requests.AddLast(request); @@ -206,38 +206,36 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc System.CriticalSection.Enter(); - if (_parent.ClientSession.ResourceStatus != 1) + if (_parent.ClientSession.State != ChannelState.Open) { System.CriticalSection.Leave(); return KernelResult.PortRemoteClosed; } - if (_activeRequest != null || _requests.Count == 0) + if (_activeRequest != null || !PickRequest(out KSessionRequest request)) { System.CriticalSection.Leave(); return KernelResult.NotFound; } - KSessionRequest request = _requests.First.Value; - - _requests.RemoveFirst(); - - if (request.SenderThread == null) + if (request.ClientThread == null) { System.CriticalSection.Leave(); return KernelResult.PortRemoteClosed; } - KThread clientThread = request.SenderThread; + KThread clientThread = request.ClientThread; KProcess clientProcess = clientThread.Owner; System.CriticalSection.Leave(); _activeRequest = request; + request.ServerProcess = serverProcess; + Message clientMsg = new Message( clientThread, request.CustomCmdBuffAddr, @@ -259,7 +257,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc void CleanUpForError() { - request.BufferDescriptorTable.UnmapServerBuffers(serverProcess.MemoryManager); + if (request.BufferDescriptorTable.UnmapServerBuffers(serverProcess.MemoryManager) == KernelResult.Success) + { + request.BufferDescriptorTable.RestoreClientBuffers(clientProcess.MemoryManager); + } CloseAllHandles(serverMsg, header, serverProcess); @@ -274,29 +275,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc System.CriticalSection.Leave(); - if (request.AsyncEvent != null) - { - System.Device.Memory.WriteInt64((long)clientMsg.DramAddress + 0, 0); - System.Device.Memory.WriteInt32((long)clientMsg.DramAddress + 8, (int)clientResult); - - clientProcess.MemoryManager.UnborrowIpcBuffer(clientMsg.Address, clientMsg.Size); - - request.AsyncEvent.Signal(); - } - else - { - System.CriticalSection.Enter(); - - if ((clientThread.SchedFlags & ThreadSchedState.LowMask) == ThreadSchedState.Paused) - { - clientThread.SignaledObj = null; - clientThread.ObjSyncResult = clientResult; - - clientThread.Reschedule(ThreadSchedState.Running); - } - - System.CriticalSection.Leave(); - } + WakeClient(request, clientResult); } if (header.ReceiveListType < 2 && header.ReceiveListOffset > clientMsg.Size) @@ -386,7 +365,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc if (clientResult == KernelResult.Success && handle != 0) { - clientResult = GetCopyObjectHandle(clientThread, handle, out newHandle); + clientResult = GetCopyObjectHandle(clientThread, serverProcess, handle, out newHandle); } serverProcess.CpuMemory.WriteInt32((long)serverMsg.Address + offset * 4, newHandle); @@ -404,7 +383,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc { if (clientResult == KernelResult.Success) { - clientResult = GetMoveObjectHandle(serverProcess, handle, out newHandle); + clientResult = GetMoveObjectHandle(clientProcess, serverProcess, handle, out newHandle); } else { @@ -640,7 +619,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc System.CriticalSection.Leave(); - KThread clientThread = request.SenderThread; + KThread clientThread = request.ClientThread; KProcess clientProcess = clientThread.Owner; Message clientMsg = new Message( @@ -662,46 +641,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc KernelResult clientResult = KernelResult.Success; KernelResult serverResult = KernelResult.Success; - void SendResultToClient() - { - if (request.AsyncEvent != null) - { - if (clientResult != KernelResult.Success) - { - System.Device.Memory.WriteInt64((long)clientMsg.DramAddress + 0, 0); - System.Device.Memory.WriteInt32((long)clientMsg.DramAddress + 8, (int)clientResult); - } - - clientProcess.MemoryManager.UnborrowIpcBuffer(clientMsg.Address, clientMsg.Size); - - request.AsyncEvent.Signal(); - } - else - { - System.CriticalSection.Enter(); - - if ((clientThread.SchedFlags & ThreadSchedState.LowMask) == ThreadSchedState.Paused) - { - clientThread.SignaledObj = null; - clientThread.ObjSyncResult = clientResult; - - clientThread.Reschedule(ThreadSchedState.Running); - } - - System.CriticalSection.Leave(); - } - } - void CleanUpForError() { - CloseAllHandles(clientMsg, header, serverProcess); + CloseAllHandles(clientMsg, header, clientProcess); - if (request.BufferDescriptorTable.UnmapServerBuffers(serverProcess.MemoryManager) == KernelResult.Success) - { - request.BufferDescriptorTable.RestoreClientBuffers(serverProcess.MemoryManager); - } - - SendResultToClient(); + CancelRequest(request, clientResult); } if (header.ReceiveListType < 2 && header.ReceiveListOffset > clientMsg.Size) @@ -737,18 +681,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc return KernelResult.CmdBufferTooSmall; } - //Close move handles. - uint pidSizeInWords = header.HasPid ? 2u : 0u; - - ulong moveHandlesAddr = serverMsg.Address + (3u + pidSizeInWords + header.CopyHandlesCount) * 4; - - for (int index = 0; index < header.MoveHandlesCount; index++) - { - int handle = serverProcess.CpuMemory.ReadInt32((long)moveHandlesAddr + index * 4); - - serverProcess.HandleTable.CloseHandle(handle); - } - //Read receive list. ulong[] receiveList = null; @@ -806,10 +738,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc if (handle != 0) { - GetCopyObjectHandle(clientThread, handle, out newHandle); + GetCopyObjectHandle(serverThread, clientProcess, handle, out newHandle); } - serverProcess.CpuMemory.WriteInt32((long)serverMsg.Address + offset * 4, newHandle); + System.Device.Memory.WriteInt32((long)clientMsg.DramAddress + offset * 4, newHandle); offset++; } @@ -824,7 +756,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc { if (clientResult == KernelResult.Success) { - clientResult = GetMoveObjectHandle(serverProcess, handle, out newHandle); + clientResult = GetMoveObjectHandle(serverProcess, clientProcess, handle, out newHandle); } else { @@ -832,7 +764,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc } } - serverProcess.CpuMemory.WriteInt32((long)serverMsg.Address + offset * 4, newHandle); + System.Device.Memory.WriteInt32((long)clientMsg.DramAddress + offset * 4, newHandle); offset++; } @@ -941,36 +873,39 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc return serverResult; } - //Wake client thread. - SendResultToClient(); + WakeClient(request, clientResult); return serverResult; } - private KernelResult GetCopyObjectHandle(KThread thread, int srcHandle, out int dstHandle) + private KernelResult GetCopyObjectHandle( + KThread srcThread, + KProcess dstProcess, + int srcHandle, + out int dstHandle) { dstHandle = 0; - KProcess process = thread.Owner; + KProcess srcProcess = srcThread.Owner; KAutoObject obj; if (srcHandle == KHandleTable.SelfProcessHandle) { - obj = process; + obj = srcProcess; } else if (srcHandle == KHandleTable.SelfThreadHandle) { - obj = thread; + obj = srcThread; } else { - obj = process.HandleTable.GetObject(srcHandle); + obj = srcProcess.HandleTable.GetObject(srcHandle); } if (obj != null) { - return process.HandleTable.GenerateHandle(obj, out dstHandle); + return dstProcess.HandleTable.GenerateHandle(obj, out dstHandle); } else { @@ -978,7 +913,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc } } - private KernelResult GetMoveObjectHandle(KProcess srcProcess, int srcHandle, out int dstHandle) + private KernelResult GetMoveObjectHandle( + KProcess srcProcess, + KProcess dstProcess, + int srcHandle, + out int dstHandle) { dstHandle = 0; @@ -986,7 +925,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc if (obj != null) { - KernelResult result = srcProcess.HandleTable.GenerateHandle(obj, out dstHandle); + KernelResult result = dstProcess.HandleTable.GenerateHandle(obj, out dstHandle); srcProcess.HandleTable.CloseHandle(srcHandle); @@ -1102,7 +1041,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc public override bool IsSignaled() { - if (_parent.ClientSession.ResourceStatus != 1) + if (_parent.ClientSession.State != ChannelState.Open) { return true; } @@ -1112,7 +1051,110 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc protected override void Destroy() { + _parent.DisconnectServer(); + + CancelAllRequests(KernelResult.PortRemoteClosed); + _parent.DecrementReferenceCount(); } + + private void CancelAllRequests(KernelResult result) + { + System.CriticalSection.Enter(); + + if (_activeRequest != null) + { + KSessionRequest request = _activeRequest; + + _activeRequest = null; + + CancelRequest(request, result); + + System.CriticalSection.Leave(); + } + else + { + System.CriticalSection.Leave(); + } + + while (PickRequest(out KSessionRequest request)) + { + CancelRequest(request, result); + } + } + + private bool PickRequest(out KSessionRequest request) + { + request = null; + + System.CriticalSection.Enter(); + + bool hasRequest = _requests.First != null; + + if (hasRequest) + { + request = _requests.First.Value; + + _requests.RemoveFirst(); + } + + System.CriticalSection.Leave(); + + return hasRequest; + } + + private void CancelRequest(KSessionRequest request, KernelResult result) + { + KProcess clientProcess = request.ClientThread.Owner; + KProcess serverProcess = request.ServerProcess; + + KernelResult unmapResult = KernelResult.Success; + + if (serverProcess != null) + { + unmapResult = request.BufferDescriptorTable.UnmapServerBuffers(serverProcess.MemoryManager); + } + + if (unmapResult == KernelResult.Success) + { + request.BufferDescriptorTable.RestoreClientBuffers(clientProcess.MemoryManager); + } + + WakeClient(request, result); + } + + private void WakeClient(KSessionRequest request, KernelResult result) + { + KThread clientThread = request.ClientThread; + KProcess clientProcess = clientThread.Owner; + + if (request.AsyncEvent != null) + { + ulong address = clientProcess.MemoryManager.GetDramAddressFromVa(request.CustomCmdBuffAddr); + + System.Device.Memory.WriteInt64((long)address + 0, 0); + System.Device.Memory.WriteInt32((long)address + 8, (int)result); + + clientProcess.MemoryManager.UnborrowIpcBuffer( + request.CustomCmdBuffAddr, + request.CustomCmdBuffSize); + + request.AsyncEvent.Signal(); + } + else + { + System.CriticalSection.Enter(); + + if ((clientThread.SchedFlags & ThreadSchedState.LowMask) == ThreadSchedState.Paused) + { + clientThread.SignaledObj = null; + clientThread.ObjSyncResult = result; + + clientThread.Reschedule(ThreadSchedState.Running); + } + + System.CriticalSection.Leave(); + } + } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Ipc/KSession.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KSession.cs index 304fab1a3e..0759aafa71 100644 --- a/Ryujinx.HLE/HOS/Kernel/Ipc/KSession.cs +++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KSession.cs @@ -17,6 +17,24 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc ClientSession = new KClientSession(system, this); } + public void DisconnectClient() + { + if (ClientSession.State == ChannelState.Open) + { + ClientSession.State = ChannelState.ClientDisconnected; + + //TODO: Wake up client, etc. + } + } + + public void DisconnectServer() + { + if (ClientSession.State == ChannelState.Open) + { + ClientSession.State = ChannelState.ServerDisconnected; + } + } + public void Dispose() { Dispose(true); diff --git a/Ryujinx.HLE/HOS/Kernel/Ipc/KSessionRequest.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KSessionRequest.cs index 05be2ecb8b..f3467f3954 100644 --- a/Ryujinx.HLE/HOS/Kernel/Ipc/KSessionRequest.cs +++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KSessionRequest.cs @@ -1,3 +1,4 @@ +using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.HOS.Kernel.Threading; namespace Ryujinx.HLE.HOS.Kernel.Ipc @@ -6,7 +7,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc { public KBufferDescriptorTable BufferDescriptorTable { get; } - public KThread SenderThread { get; } + public KThread ClientThread { get; } + + public KProcess ServerProcess { get; set; } public KWritableEvent AsyncEvent { get; } @@ -14,11 +17,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc public ulong CustomCmdBuffSize { get; } public KSessionRequest( - KThread senderThread, + KThread clientThread, ulong customCmdBuffAddr, ulong customCmdBuffSize) { - SenderThread = senderThread; + ClientThread = clientThread; CustomCmdBuffAddr = customCmdBuffAddr; CustomCmdBuffSize = customCmdBuffSize; diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs index a75a6cab81..7a40139ccc 100644 --- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs +++ b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs @@ -1778,7 +1778,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory if (visitedSize != 0) { - InsertBlock(address, size, SetIpcMappingPermissions, permissionMask); + InsertBlock(address, visitedSize / PageSize, SetIpcMappingPermissions, permissionMask); } } @@ -1850,14 +1850,17 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory firstPageFillAddress += unusedSizeBefore + copySize; - unusedSizeAfter = addressRounded - endAddr; + unusedSizeAfter = addressRounded > endAddr ? addressRounded - endAddr : 0; } else { unusedSizeAfter = PageSize; } - _system.Device.Memory.Set(firstPageFillAddress, 0, unusedSizeAfter); + if (unusedSizeAfter != 0) + { + _system.Device.Memory.Set(firstPageFillAddress, 0, unusedSizeAfter); + } KPageList pages = new KPageList(); @@ -1989,15 +1992,15 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory if (pageList.Nodes.Count != 0) { - if (MapPages(va, pageList, permission) != KernelResult.Success) + KernelResult result = MapPages(va, pageList, permission); + + if (result != KernelResult.Success) { - throw new InvalidOperationException("Unexpected failure while trying to map pages."); + return result; } } - else - { - InsertBlock(va, neededPagesCount, state, permission); - } + + InsertBlock(va, neededPagesCount, state, permission); mappedVa = va; } diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs index 821a2afb4b..2ab21d26b0 100644 --- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcSystem.cs @@ -666,6 +666,8 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall { currentProcess.HandleTable.SetReservedHandleObj(handle, session); + session.DecrementReferenceCount(); + sessionHandle = handle; result = KernelResult.Success; @@ -933,9 +935,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.MaximumExceeded; } - KPort port = new KPort(_system); - - port.Initialize(maxSessions, isLight, (long)namePtr); + KPort port = new KPort(_system, maxSessions, isLight, (long)namePtr); KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); @@ -980,7 +980,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KClientPort.RemoveName(_system, name); } - KPort port = new KPort(_system); + KPort port = new KPort(_system, maxSessions, false, 0); KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); @@ -991,8 +991,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return result; } - port.Initialize(maxSessions, false, 0); - result = port.ClientPort.SetName(name); if (result != KernelResult.Success) diff --git a/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs b/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs index d09c92a4a0..8b31f2f93f 100644 --- a/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs +++ b/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs @@ -32,9 +32,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm public static void InitializePort(Horizon system) { - KPort port = new KPort(system); - - port.Initialize(256, false, 0); + KPort port = new KPort(system, 256, false, 0); port.ClientPort.SetName("sm:"); @@ -110,11 +108,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm return ErrorCode.MakeError(ErrorModule.Sm, SmErr.InvalidName); } - System.Console.WriteLine("register service " + name + " " + maxSessions); - - KPort port = new KPort(context.Device.System); - - port.Initialize(maxSessions, isLight, 0); + KPort port = new KPort(context.Device.System, maxSessions, isLight, 0); if (!_registeredServices.TryAdd(name, port)) {