示例#1
0
        public KernelResult Map(ulong address, ulong size, KMemoryPermission perm)
        {
            if (_pageCount != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
            {
                return(KernelResult.InvalidSize);
            }

            lock (_lock)
            {
                if (_isMapped)
                {
                    return(KernelResult.InvalidState);
                }

                KProcess proc = KernelStatic.GetCurrentProcess();

                // TODO: Mark pages as MemoryState.CodeWritable
                KernelResult resultCode = proc.MemoryManager.MapPages(address, _hostPagelist, KMemoryPermission.ReadAndWrite);
                if (resultCode != KernelResult.Success)
                {
                    return(KernelResult.InvalidState);
                }

                _isMapped = true;
            }

            return(KernelResult.Success);
        }
示例#2
0
        /// <inheritdoc/>
        protected override KernelResult MapPages(ulong address, KPageList pageList, KMemoryPermission permission, bool shouldFillPages, byte fillValue)
        {
            using var scopedPageList = new KScopedPageList(Context.MemoryManager, pageList);

            ulong currentVa = address;

            foreach (var pageNode in pageList)
            {
                ulong addr = pageNode.Address - DramMemoryMap.DramBase;
                ulong size = pageNode.PagesCount * PageSize;

                Context.Memory.Commit(addr, size);

                _cpuMemory.Map(currentVa, Context.Memory.GetPointer(addr, size), size);

                if (shouldFillPages)
                {
                    _cpuMemory.Fill(currentVa, size, fillValue);
                }

                currentVa += size;
            }

            scopedPageList.SignalSuccess();

            return(KernelResult.Success);
        }
示例#3
0
        public KernelResult Map(ulong address, ulong size, KMemoryPermission perm)
        {
            if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
            {
                return(KernelResult.InvalidSize);
            }

            lock (_lock)
            {
                if (_isMapped)
                {
                    return(KernelResult.InvalidState);
                }

                KProcess process = KernelStatic.GetCurrentProcess();

                KernelResult result = process.MemoryManager.MapPages(address, _pageList, MemoryState.CodeWritable, KMemoryPermission.ReadAndWrite);

                if (result != KernelResult.Success)
                {
                    return(result);
                }

                _isMapped = true;
            }

            return(KernelResult.Success);
        }
示例#4
0
        public KernelResult MapToOwner(ulong address, ulong size, KMemoryPermission permission)
        {
            if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
            {
                return(KernelResult.InvalidSize);
            }

            lock (_lock)
            {
                if (_isOwnerMapped)
                {
                    return(KernelResult.InvalidState);
                }

                Debug.Assert(permission == KMemoryPermission.Read || permission == KMemoryPermission.ReadAndExecute);

                KernelResult result = Owner.MemoryManager.MapPages(address, _pageList, MemoryState.CodeReadOnly, permission);

                if (result != KernelResult.Success)
                {
                    return(result);
                }

                _isOwnerMapped = true;
            }

            return(KernelResult.Success);
        }
示例#5
0
 public void SetState(KMemoryPermission permission, MemoryState state, MemoryAttribute attribute)
 {
     Permission = permission;
     State      = state;
     Attribute &= MemoryAttribute.IpcAndDeviceMapped;
     Attribute |= attribute;
 }
示例#6
0
 public KernelResult SetMemoryPermission64(
     [R(0)] ulong address,
     [R(1)] ulong size,
     [R(2)] KMemoryPermission permission)
 {
     return(_syscall.SetMemoryPermission(address, size, permission));
 }
示例#7
0
 public KernelResult SetMemoryPermission64(
     [R(0)] ulong position,
     [R(1)] ulong size,
     [R(2)] KMemoryPermission permission)
 {
     return(_syscall.SetMemoryPermission(position, size, permission));
 }
示例#8
0
        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);
            }

            KernelResult result = memoryManager.MapPages(address, pageList, MemoryState.SharedMemory, permission);

            if (result == KernelResult.Success && !memoryManager.SupportsMemoryAliasing)
            {
                _storage.Borrow(process, address);
            }

            return(result);
        }
示例#9
0
        public KernelResult MapIntoProcess(
            KMemoryManager memoryManager,
            ulong address,
            ulong size,
            KProcess process,
            KMemoryPermission permission)
        {
            ulong pagesCountRounded = BitUtils.DivRoundUp(size, KMemoryManager.PageSize);

            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));
        }
示例#10
0
        public KernelResult MapIntoProcess(
            KPageTableBase memoryManager,
            ulong address,
            ulong size,
            KProcess process,
            KMemoryPermission permission)
        {
            if (_pageList.GetPagesCount() != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
            {
                return(KernelResult.InvalidSize);
            }

            if (permission != Permission || _isMapped)
            {
                return(KernelResult.InvalidState);
            }

            MemoryState state = Permission == KMemoryPermission.None ? MemoryState.TransferMemoryIsolated : MemoryState.TransferMemory;

            KernelResult result = memoryManager.MapPages(address, _pageList, state, KMemoryPermission.ReadAndWrite);

            if (result == KernelResult.Success)
            {
                _isMapped = true;
            }

            return(result);
        }
示例#11
0
 public KernelResult CreateTransferMemory64(
     [R(1)] ulong address,
     [R(2)] ulong size,
     [R(3)] KMemoryPermission permission,
     [R(1)] out int handle)
 {
     return(_syscall.CreateTransferMemory(address, size, permission, out handle));
 }
示例#12
0
        public KTransferMemory(KernelContext context, SharedMemoryStorage storage) : base(context)
        {
            _pageList  = storage.GetPageList();
            Permission = KMemoryPermission.ReadAndWrite;

            _hasBeenInitialized = true;
            _isMapped           = false;
        }
示例#13
0
 public KernelResult CreateTransferMemory32(
     [R(1)] uint address,
     [R(2)] uint size,
     [R(3)] KMemoryPermission permission,
     [R(1)] out int handle)
 {
     return(_syscall.CreateTransferMemory(out handle, address, size, permission));
 }
示例#14
0
        public void InsertBlock(
            ulong baseAddress,
            ulong pagesCount,
            BlockMutator blockMutate,
            KMemoryPermission permission = KMemoryPermission.None)
        {
            // Inserts new block at the list, replacing and splitting
            // existing blocks as needed, then calling the callback
            // function on the new block.
            int oldCount = _blocks.Count;

            ulong endAddr = baseAddress + pagesCount * PageSize;

            LinkedListNode <KMemoryBlock> node = _blocks.First;

            while (node != null)
            {
                LinkedListNode <KMemoryBlock> newNode = node;

                KMemoryBlock currBlock = node.Value;

                ulong currBaseAddr = currBlock.BaseAddress;
                ulong currEndAddr  = currBlock.PagesCount * PageSize + currBaseAddr;

                if (baseAddress < currEndAddr && currBaseAddr < endAddr)
                {
                    if (baseAddress > currBaseAddr)
                    {
                        _blocks.AddBefore(node, currBlock.SplitRightAtAddress(baseAddress));
                    }

                    if (endAddr < currEndAddr)
                    {
                        newNode = _blocks.AddBefore(node, currBlock.SplitRightAtAddress(endAddr));
                    }

                    KMemoryBlock newBlock = newNode.Value;

                    blockMutate(newBlock, permission);

                    newNode = MergeEqualStateNeighbors(newNode);
                }

                if (currEndAddr - 1 >= endAddr - 1)
                {
                    break;
                }

                node = newNode.Next;
            }

            _slabManager.Count += _blocks.Count - oldCount;

            ValidateInternalState();
        }
示例#15
0
        public void InsertBlock(
            ulong baseAddress,
            ulong pagesCount,
            BlockMutator blockMutate,
            KMemoryPermission permission = KMemoryPermission.None)
        {
            // Inserts new block at the list, replacing and splitting
            // existing blocks as needed, then calling the callback
            // function on the new block.

            int oldCount = _blockTree.Count;

            ulong endAddr = baseAddress + pagesCount * PageSize;

            KMemoryBlock currBlock = FindBlock(baseAddress);

            while (currBlock != null)
            {
                ulong currBaseAddr = currBlock.BaseAddress;
                ulong currEndAddr  = currBlock.PagesCount * PageSize + currBaseAddr;

                if (baseAddress < currEndAddr && currBaseAddr < endAddr)
                {
                    if (baseAddress > currBaseAddr)
                    {
                        KMemoryBlock newBlock = currBlock.SplitRightAtAddress(baseAddress);
                        _blockTree.Add(newBlock);
                    }

                    if (endAddr < currEndAddr)
                    {
                        KMemoryBlock newBlock = currBlock.SplitRightAtAddress(endAddr);
                        _blockTree.Add(newBlock);
                        currBlock = newBlock;
                    }

                    blockMutate(currBlock, permission);

                    currBlock = MergeEqualStateNeighbors(currBlock);
                }

                if (currEndAddr - 1 >= endAddr - 1)
                {
                    break;
                }

                currBlock = currBlock.Successor;
            }

            _slabManager.Count += _blockTree.Count - oldCount;

            ValidateInternalState();
        }
示例#16
0
 public KSharedMemory(
     KernelContext context,
     KPageList pageList,
     long ownerPid,
     KMemoryPermission ownerPermission,
     KMemoryPermission userPermission) : base(context)
 {
     _pageList        = pageList;
     _ownerPid        = ownerPid;
     _ownerPermission = ownerPermission;
     _userPermission  = userPermission;
 }
示例#17
0
 public KSharedMemory(
     KernelContext context,
     SharedMemoryStorage storage,
     long ownerPid,
     KMemoryPermission ownerPermission,
     KMemoryPermission userPermission) : base(context)
 {
     _storage         = storage;
     _ownerPid        = ownerPid;
     _ownerPermission = ownerPermission;
     _userPermission  = userPermission;
 }
示例#18
0
 public KSharedMemory(
     KernelContext context,
     SharedMemoryStorage storage,
     ulong ownerPid,
     KMemoryPermission ownerPermission,
     KMemoryPermission userPermission) : base(context)
 {
     _pageList        = storage.GetPageList();
     _ownerPid        = ownerPid;
     _ownerPermission = ownerPermission;
     _userPermission  = userPermission;
 }
示例#19
0
        public KernelResult SetProcessMemoryPermission32(
            [R(0)] int handle,
            [R(1)] uint sizeLow,
            [R(2)] uint srcLow,
            [R(3)] uint srcHigh,
            [R(4)] uint sizeHigh,
            [R(5)] KMemoryPermission permission)
        {
            ulong src  = srcLow | ((ulong)srcHigh << 32);
            ulong size = sizeLow | ((ulong)sizeHigh << 32);

            return(_syscall.SetProcessMemoryPermission(handle, src, size, permission));
        }
示例#20
0
        /// <inheritdoc/>
        protected override KernelResult MapPages(ulong address, KPageList pageList, KMemoryPermission permission, bool shouldFillPages, byte fillValue)
        {
            ulong pagesCount = pageList.GetPagesCount();

            _cpuMemory.Map(address, 0, pagesCount * PageSize);

            if (shouldFillPages)
            {
                _cpuMemory.Fill(address, pagesCount * PageSize, fillValue);
            }

            return(KernelResult.Success);
        }
示例#21
0
 public KMemoryBlock(
     ulong baseAddress,
     ulong pagesCount,
     MemoryState state,
     KMemoryPermission permission,
     MemoryAttribute attribute,
     int ipcRefCount    = 0,
     int deviceRefCount = 0)
 {
     BaseAddress    = baseAddress;
     PagesCount     = pagesCount;
     State          = state;
     Attribute      = attribute;
     Permission     = permission;
     IpcRefCount    = ipcRefCount;
     DeviceRefCount = deviceRefCount;
 }
示例#22
0
#pragma warning restore CS0414

        public MemoryInfo(
            ulong address,
            ulong size,
            MemoryState state,
            MemoryAttribute attribute,
            KMemoryPermission permission,
            int ipcRefCount,
            int deviceRefCount)
        {
            Address        = address;
            Size           = size;
            State          = state;
            Attribute      = attribute;
            Permission     = permission;
            IpcRefCount    = ipcRefCount;
            DeviceRefCount = deviceRefCount;
            _padding       = 0;
        }
示例#23
0
        public void SetIpcMappingPermission(KMemoryPermission newPermission)
        {
            int oldIpcRefCount = IpcRefCount++;

            if ((ushort)IpcRefCount == 0)
            {
                throw new InvalidOperationException("IPC reference count increment overflowed.");
            }

            if (oldIpcRefCount == 0)
            {
                SourcePermission = Permission;

                Permission &= ~KMemoryPermission.ReadAndWrite;
                Permission |= KMemoryPermission.ReadAndWrite & newPermission;
            }

            Attribute |= MemoryAttribute.IpcMapped;
        }
示例#24
0
        public KernelResult MapIntoProcess(
            KPageTableBase memoryManager,
            ulong address,
            ulong size,
            KProcess process,
            KMemoryPermission permission)
        {
            if (_storage == null)
            {
                throw new NotImplementedException();
            }

            ulong pagesCountRounded = BitUtils.DivRoundUp(size, KPageTableBase.PageSize);

            var pageList = _storage.GetPageList();

            if (pageList.GetPagesCount() != pagesCountRounded)
            {
                return(KernelResult.InvalidSize);
            }

            if (permission != Permission || _isMapped)
            {
                return(KernelResult.InvalidState);
            }

            MemoryState state = Permission == KMemoryPermission.None ? MemoryState.TransferMemoryIsolated : MemoryState.TransferMemory;

            KernelResult result = memoryManager.MapPages(address, pageList, state, KMemoryPermission.ReadAndWrite);

            if (result == KernelResult.Success)
            {
                _isMapped = true;

                if (!memoryManager.SupportsMemoryAliasing)
                {
                    _storage.Borrow(process, address);
                }
            }

            return(result);
        }
示例#25
0
        public KernelResult Initialize(ulong address, ulong size, KMemoryPermission permission)
        {
            KProcess creator = KernelStatic.GetCurrentProcess();

            _creator = creator;

            KernelResult result = creator.MemoryManager.BorrowTransferMemory(_pageList, address, size, permission);

            if (result != KernelResult.Success)
            {
                return(result);
            }

            creator.IncrementReferenceCount();

            Permission          = permission;
            Address             = address;
            _hasBeenInitialized = true;
            _isMapped           = false;

            return(result);
        }
示例#26
0
        public KernelResult MapToOwner(ulong address, ulong size, KMemoryPermission permission)
        {
            if (_pageCount != BitUtils.DivRoundUp(size, KPageTableBase.PageSize))
            {
                return(KernelResult.InvalidSize);
            }

            lock (_lock)
            {
                if (_isOwnerMapped)
                {
                    return(KernelResult.InvalidState);
                }

                Debug.Assert(permission == KMemoryPermission.Read || permission == KMemoryPermission.ReadAndExecute);

                // TODO: Mark pages as MemoryState.CodeReadOnly
                _owner.MemoryManager.MapPages(address, _hostPagelist, permission == KMemoryPermission.Read ? KMemoryPermission.Read :  KMemoryPermission.ReadAndExecute);

                _isOwnerMapped = true;
            }

            return(KernelResult.Success);
        }
示例#27
0
 public KernelResult SetProcessMemoryPermission64([R(0)] int handle, [R(1)] ulong src, [R(2)] ulong size, [R(3)] KMemoryPermission permission)
 {
     return(_syscall.SetProcessMemoryPermission(handle, src, size, permission));
 }
示例#28
0
 public KernelResult MapTransferMemory64([R(0)] int handle, [R(1)] ulong address, [R(2)] ulong size, [R(3)] KMemoryPermission permission)
 {
     return(_syscall.MapTransferMemory(handle, address, size, permission));
 }
示例#29
0
        /// <inheritdoc/>
        protected override KernelResult MapPages(ulong dstVa, ulong pagesCount, ulong srcPa, KMemoryPermission permission, bool shouldFillPages, byte fillValue)
        {
            ulong size = pagesCount * PageSize;

            Context.Memory.Commit(srcPa - DramMemoryMap.DramBase, size);

            _cpuMemory.Map(dstVa, Context.Memory.GetPointer(srcPa - DramMemoryMap.DramBase, size), size);

            if (DramMemoryMap.IsHeapPhysicalAddress(srcPa))
            {
                Context.MemoryManager.IncrementPagesReferenceCount(srcPa, pagesCount);
            }

            if (shouldFillPages)
            {
                _cpuMemory.Fill(dstVa, size, fillValue);
            }

            return(KernelResult.Success);
        }
示例#30
0
        /// <inheritdoc/>
        protected override KernelResult UnmapMemory(ulong dst, ulong src, ulong pagesCount, KMemoryPermission oldDstPermission, KMemoryPermission newSrcPermission)
        {
            ulong size = pagesCount * PageSize;

            var srcRanges = GetPhysicalRegions(src, size);
            var dstRanges = GetPhysicalRegions(dst, size);

            if (!dstRanges.SequenceEqual(srcRanges))
            {
                return(KernelResult.InvalidMemRange);
            }

            KernelResult result = Unmap(dst, pagesCount);

            if (result != KernelResult.Success)
            {
                return(result);
            }

            result = Reprotect(src, pagesCount, newSrcPermission);

            if (result != KernelResult.Success)
            {
                KernelResult mapResult = MapPages(dst, dstRanges, oldDstPermission);
                Debug.Assert(mapResult == KernelResult.Success);
            }

            return(result);
        }