aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2021-02-07 20:54:49 -0300
committerGitHub <noreply@github.com>2021-02-08 10:54:49 +1100
commit5ea7d77981df75f4eede220bf25926af177ef808 (patch)
tree445e5ca1f647595110109172cf8de616b7bb68d4 /Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs
parent40797a1283ce9119f5f132693089c42442a4aa71 (diff)
Fix inter-process data copy on non-contiguous physical regions (#1988)
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs')
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs34
1 files changed, 26 insertions, 8 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs
index 5a8e8e3b..5b6df53b 100644
--- a/Ryujinx.HLE/HOS/Kernel/Memory/KMemoryManager.cs
+++ b/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;