/ src / Ryujinx.HLE / HOS / Kernel / Memory / KSharedMemory.cs
KSharedMemory.cs
 1  using Ryujinx.Common;
 2  using Ryujinx.HLE.HOS.Kernel.Common;
 3  using Ryujinx.HLE.HOS.Kernel.Process;
 4  using Ryujinx.Horizon.Common;
 5  
 6  namespace Ryujinx.HLE.HOS.Kernel.Memory
 7  {
 8      class KSharedMemory : KAutoObject
 9      {
10          private readonly KPageList _pageList;
11  
12          private readonly ulong _ownerPid;
13  
14          private readonly KMemoryPermission _ownerPermission;
15          private readonly KMemoryPermission _userPermission;
16  
17          public KSharedMemory(
18              KernelContext context,
19              SharedMemoryStorage storage,
20              ulong ownerPid,
21              KMemoryPermission ownerPermission,
22              KMemoryPermission userPermission) : base(context)
23          {
24              _pageList = storage.GetPageList();
25              _ownerPid = ownerPid;
26              _ownerPermission = ownerPermission;
27              _userPermission = userPermission;
28          }
29  
30          public Result MapIntoProcess(
31              KPageTableBase memoryManager,
32              ulong address,
33              ulong size,
34              KProcess process,
35              KMemoryPermission permission)
36          {
37              if (_pageList.GetPagesCount() != BitUtils.DivRoundUp<ulong>(size, KPageTableBase.PageSize))
38              {
39                  return KernelResult.InvalidSize;
40              }
41  
42              KMemoryPermission expectedPermission = process.Pid == _ownerPid
43                  ? _ownerPermission
44                  : _userPermission;
45  
46              if (permission != expectedPermission)
47              {
48                  return KernelResult.InvalidPermission;
49              }
50  
51              return memoryManager.MapPages(address, _pageList, MemoryState.SharedMemory, permission);
52          }
53  
54          public Result UnmapFromProcess(KPageTableBase memoryManager, ulong address, ulong size, KProcess process)
55          {
56              if (_pageList.GetPagesCount() != BitUtils.DivRoundUp<ulong>(size, KPageTableBase.PageSize))
57              {
58                  return KernelResult.InvalidSize;
59              }
60  
61              return memoryManager.UnmapPages(address, _pageList, MemoryState.SharedMemory);
62          }
63      }
64  }