KSharedMemory.cs 2.5 KB

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