Jelajahi Sumber

Fix inter-process data copy on non-contiguous physical regions (#1988)

gdkchan 5 tahun lalu
induk
melakukan
5ea7d77981
1 mengubah file dengan 26 tambahan dan 8 penghapusan
  1. 26 8
      Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs

+ 26 - 8
Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs

@@ -1506,15 +1506,33 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
                 {
                     KProcess currentProcess = KernelStatic.GetCurrentProcess();
 
-                    serverAddress = currentProcess.MemoryManager.GetDramAddressFromVa(serverAddress);
-
-                    if (toServer)
-                    {
-                        _context.Memory.Copy(serverAddress, GetDramAddressFromVa(clientAddress), size);
-                    }
-                    else
+                    while (size > 0)
                     {
-                        _context.Memory.Copy(GetDramAddressFromVa(clientAddress), serverAddress, size);
+                        ulong copySize = Math.Min(PageSize - (serverAddress & (PageSize - 1)), PageSize - (clientAddress & (PageSize - 1)));
+
+                        if (copySize > size)
+                        {
+                            copySize = size;
+                        }
+
+                        ulong serverDramAddr = currentProcess.MemoryManager.GetDramAddressFromVa(serverAddress);
+                        ulong clientDramAddr = GetDramAddressFromVa(clientAddress);
+
+                        if (serverDramAddr != clientDramAddr)
+                        {
+                            if (toServer)
+                            {
+                                _context.Memory.Copy(serverDramAddr, clientDramAddr, copySize);
+                            }
+                            else
+                            {
+                                _context.Memory.Copy(clientDramAddr, serverDramAddr, copySize);
+                            }
+                        }
+
+                        serverAddress += copySize;
+                        clientAddress += copySize;
+                        size -= copySize;
                     }
 
                     return KernelResult.Success;