using Ryujinx.Common; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Process; namespace Ryujinx.HLE.HOS.Kernel.Memory { class KSharedMemory : KAutoObject { private readonly SharedMemoryStorage _storage; private readonly long _ownerPid; private readonly KMemoryPermission _ownerPermission; private readonly KMemoryPermission _userPermission; public KSharedMemory( KernelContext context, SharedMemoryStorage storage, long ownerPid, KMemoryPermission ownerPermission, KMemoryPermission userPermission) : base(context) { _storage = storage; _ownerPid = ownerPid; _ownerPermission = ownerPermission; _userPermission = userPermission; } public KernelResult MapIntoProcess( KPageTableBase memoryManager, ulong address, ulong size, KProcess process, KMemoryPermission permission) { ulong pagesCountRounded = BitUtils.DivRoundUp(size, KPageTableBase.PageSize); var pageList = _storage.GetPageList(); if (pageList.GetPagesCount() != pagesCountRounded) { return KernelResult.InvalidSize; } KMemoryPermission expectedPermission = process.Pid == _ownerPid ? _ownerPermission : _userPermission; if (permission != expectedPermission) { return KernelResult.InvalidPermission; } return memoryManager.MapPages(address, pageList, MemoryState.SharedMemory, permission); } public KernelResult UnmapFromProcess(KPageTableBase memoryManager, ulong address, ulong size, KProcess process) { ulong pagesCountRounded = BitUtils.DivRoundUp(size, KPageTableBase.PageSize); var pageList = _storage.GetPageList(); ulong pagesCount = pageList.GetPagesCount(); if (pagesCount != pagesCountRounded) { return KernelResult.InvalidSize; } return memoryManager.UnmapPages(address, pagesCount, pageList, MemoryState.SharedMemory); } } }