diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2020-07-17 01:19:07 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-17 14:19:07 +1000 |
| commit | 9f6b24edfddf871320290463437b3f3cb7e29006 (patch) | |
| tree | 4b8b45db5fe931ac37f843778c58a2d676fe3fba /Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs | |
| parent | 46f8cef6a9e4a305803f1356446e25ce54909130 (diff) | |
Improve kernel IPC related syscalls (#1379)
* Implement session count decrement when the handle is closed
* Remove unused field
* Implement SendSyncRequestWithUserBuffer, SendAsyncRequestWithUserBuffer and ReplyAndReceiveWithUserBuffer syscalls
* Nits
* Fix swapped copy dst/src
* Add missing pointer buffer descriptor write on reply
* Fix IPC unaligned buffer copy and restoring client attributes on reply
* Oops
* Fix SetIpcMappingPermission
* Fix unaligned copy bugs
* Free memory used for temporary IPC buffers
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs b/Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs index 70b54d05..48669832 100644 --- a/Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs +++ b/Ryujinx.HLE/HOS/Kernel/Ipc/KServerSession.cs @@ -633,7 +633,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc { CloseAllHandles(clientMsg, serverHeader, clientProcess); - CancelRequest(request, clientResult); + FinishRequest(request, clientResult); } if (clientHeader.ReceiveListType < 2 && @@ -770,6 +770,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc PointerBufferDesc descriptor = new PointerBufferDesc(pointerDesc); + ulong recvListBufferAddress = 0; + if (descriptor.BufferSize != 0) { clientResult = GetReceiveListAddress( @@ -778,8 +780,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc clientHeader.ReceiveListType, serverHeader.MessageSizeInWords, receiveList, - ref recvListDstOffset, - out ulong recvListBufferAddress); + ref recvListDstOffset, + out recvListBufferAddress); if (clientResult != KernelResult.Success) { @@ -806,6 +808,17 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc } } + ulong dstDescAddress = clientMsg.DramAddress + offset * 4; + + ulong clientPointerDesc = + (recvListBufferAddress << 32) | + ((recvListBufferAddress >> 20) & 0xf000) | + ((recvListBufferAddress >> 30) & 0xffc0); + + clientPointerDesc |= pointerDesc & 0xffff000f; + + KernelContext.Memory.Write(dstDescAddress + 0, clientPointerDesc); + offset += 2; } @@ -860,16 +873,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc } // Unmap buffers from server. - clientResult = request.BufferDescriptorTable.UnmapServerBuffers(serverProcess.MemoryManager); - - if (clientResult != KernelResult.Success) - { - CleanUpForError(); - - return serverResult; - } - - WakeClientThread(request, clientResult); + FinishRequest(request, clientResult); return serverResult; } @@ -1109,7 +1113,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc { foreach (KSessionRequest request in IterateWithRemovalOfAllRequests()) { - CancelRequest(request, KernelResult.PortRemoteClosed); + FinishRequest(request, KernelResult.PortRemoteClosed); } } @@ -1180,7 +1184,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc return hasRequest; } - private void CancelRequest(KSessionRequest request, KernelResult result) + private void FinishRequest(KSessionRequest request, KernelResult result) { KProcess clientProcess = request.ClientThread.Owner; KProcess serverProcess = request.ServerProcess; @@ -1221,14 +1225,15 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc { KProcess clientProcess = request.ClientThread.Owner; - ulong address = clientProcess.MemoryManager.GetDramAddressFromVa(request.CustomCmdBuffAddr); + if (result != KernelResult.Success) + { + ulong address = clientProcess.MemoryManager.GetDramAddressFromVa(request.CustomCmdBuffAddr); - KernelContext.Memory.Write<ulong>(address, 0); - KernelContext.Memory.Write(address + 8, (int)result); + KernelContext.Memory.Write<ulong>(address, 0); + KernelContext.Memory.Write(address + 8, (int)result); + } - clientProcess.MemoryManager.UnborrowIpcBuffer( - request.CustomCmdBuffAddr, - request.CustomCmdBuffSize); + clientProcess.MemoryManager.UnborrowIpcBuffer(request.CustomCmdBuffAddr, request.CustomCmdBuffSize); request.AsyncEvent.Signal(); } |
