forked from Mirror/Ryujinx
Fix inter-process data copy on non-contiguous physical regions (#1988)
This commit is contained in:
parent
40797a1283
commit
5ea7d77981
1 changed files with 26 additions and 8 deletions
|
@ -1506,15 +1506,33 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
||||||
{
|
{
|
||||||
KProcess currentProcess = KernelStatic.GetCurrentProcess();
|
KProcess currentProcess = KernelStatic.GetCurrentProcess();
|
||||||
|
|
||||||
serverAddress = currentProcess.MemoryManager.GetDramAddressFromVa(serverAddress);
|
while (size > 0)
|
||||||
|
{
|
||||||
|
ulong copySize = Math.Min(PageSize - (serverAddress & (PageSize - 1)), PageSize - (clientAddress & (PageSize - 1)));
|
||||||
|
|
||||||
if (toServer)
|
if (copySize > size)
|
||||||
{
|
{
|
||||||
_context.Memory.Copy(serverAddress, GetDramAddressFromVa(clientAddress), size);
|
copySize = size;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
ulong serverDramAddr = currentProcess.MemoryManager.GetDramAddressFromVa(serverAddress);
|
||||||
_context.Memory.Copy(GetDramAddressFromVa(clientAddress), serverAddress, size);
|
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;
|
return KernelResult.Success;
|
||||||
|
|
Loading…
Reference in a new issue