aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-05-03 08:16:31 -0300
committerGitHub <noreply@github.com>2022-05-03 13:16:31 +0200
commit1cbca5eecbb6b7bce94dca864b5cffda4db02d39 (patch)
treeec2149ce096c63bda078b5f912fed7e1a13bf8d0 /Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
parent95017b8c66f70406e926b278ecdd6d4ec0a93110 (diff)
Implement code memory syscalls (#2958)1.1.111
* Implement code memory syscalls * Remove owner process validation * Add 32-bit code memory syscalls * Remove unused field
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs')
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs146
1 files changed, 146 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs b/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
index 518a0f09..94e8fb6a 100644
--- a/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Memory/KPageTableBase.cs
@@ -1095,6 +1095,77 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
}
}
+ public KernelResult UnmapProcessMemory(ulong dst, ulong size, KPageTableBase srcPageTable, ulong src)
+ {
+ lock (_blockManager)
+ {
+ lock (srcPageTable._blockManager)
+ {
+ bool success = CheckRange(
+ dst,
+ size,
+ MemoryState.Mask,
+ MemoryState.ProcessMemory,
+ KMemoryPermission.ReadAndWrite,
+ KMemoryPermission.ReadAndWrite,
+ MemoryAttribute.Mask,
+ MemoryAttribute.None,
+ MemoryAttribute.IpcAndDeviceMapped,
+ out _,
+ out _,
+ out _);
+
+ success &= srcPageTable.CheckRange(
+ src,
+ size,
+ MemoryState.MapProcessAllowed,
+ MemoryState.MapProcessAllowed,
+ KMemoryPermission.None,
+ KMemoryPermission.None,
+ MemoryAttribute.Mask,
+ MemoryAttribute.None,
+ MemoryAttribute.IpcAndDeviceMapped,
+ out _,
+ out _,
+ out _);
+
+ if (!success)
+ {
+ return KernelResult.InvalidMemState;
+ }
+
+ KPageList srcPageList = new KPageList();
+ KPageList dstPageList = new KPageList();
+
+ srcPageTable.GetPhysicalRegions(src, size, srcPageList);
+ GetPhysicalRegions(dst, size, dstPageList);
+
+ if (!dstPageList.IsEqual(srcPageList))
+ {
+ return KernelResult.InvalidMemRange;
+ }
+ }
+
+ if (!_slabManager.CanAllocate(MaxBlocksNeededForInsertion))
+ {
+ return KernelResult.OutOfResource;
+ }
+
+ ulong pagesCount = size / PageSize;
+
+ KernelResult result = Unmap(dst, pagesCount);
+
+ if (result != KernelResult.Success)
+ {
+ return result;
+ }
+
+ _blockManager.InsertBlock(dst, pagesCount, MemoryState.Unmapped);
+
+ return KernelResult.Success;
+ }
+ }
+
public KernelResult SetProcessMemoryPermission(ulong address, ulong size, KMemoryPermission permission)
{
lock (_blockManager)
@@ -2023,6 +2094,49 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
block.RestoreIpcMappingPermission();
}
+ public KernelResult GetPagesIfStateEquals(
+ ulong address,
+ ulong size,
+ MemoryState stateMask,
+ MemoryState stateExpected,
+ KMemoryPermission permissionMask,
+ KMemoryPermission permissionExpected,
+ MemoryAttribute attributeMask,
+ MemoryAttribute attributeExpected,
+ KPageList pageList)
+ {
+ if (!InsideAddrSpace(address, size))
+ {
+ return KernelResult.InvalidMemState;
+ }
+
+ lock (_blockManager)
+ {
+ if (CheckRange(
+ address,
+ size,
+ stateMask | MemoryState.IsPoolAllocated,
+ stateExpected | MemoryState.IsPoolAllocated,
+ permissionMask,
+ permissionExpected,
+ attributeMask,
+ attributeExpected,
+ MemoryAttribute.IpcAndDeviceMapped,
+ out _,
+ out _,
+ out _))
+ {
+ GetPhysicalRegions(address, size, pageList);
+
+ return KernelResult.Success;
+ }
+ else
+ {
+ return KernelResult.InvalidMemState;
+ }
+ }
+ }
+
public KernelResult BorrowIpcBuffer(ulong address, ulong size)
{
return SetAttributesAndChangePermission(
@@ -2054,6 +2168,22 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
pageList);
}
+ public KernelResult BorrowCodeMemory(KPageList pageList, ulong address, ulong size)
+ {
+ return SetAttributesAndChangePermission(
+ address,
+ size,
+ MemoryState.CodeMemoryAllowed,
+ MemoryState.CodeMemoryAllowed,
+ KMemoryPermission.Mask,
+ KMemoryPermission.ReadAndWrite,
+ MemoryAttribute.Mask,
+ MemoryAttribute.None,
+ KMemoryPermission.None,
+ MemoryAttribute.Borrowed,
+ pageList);
+ }
+
private KernelResult SetAttributesAndChangePermission(
ulong address,
ulong size,
@@ -2159,6 +2289,22 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
pageList);
}
+ public KernelResult UnborrowCodeMemory(ulong address, ulong size, KPageList pageList)
+ {
+ return ClearAttributesAndChangePermission(
+ address,
+ size,
+ MemoryState.CodeMemoryAllowed,
+ MemoryState.CodeMemoryAllowed,
+ KMemoryPermission.None,
+ KMemoryPermission.None,
+ MemoryAttribute.Mask,
+ MemoryAttribute.Borrowed,
+ KMemoryPermission.ReadAndWrite,
+ MemoryAttribute.Borrowed,
+ pageList);
+ }
+
private KernelResult ClearAttributesAndChangePermission(
ulong address,
ulong size,