memobj-r0drv-nt.cpp revision 547d46bba272294fddc7601967690c9350914527
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * innotek Portable Runtime - Ring-0 Memory Objects, NT.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * Copyright (C) 2006-2007 innotek GmbH
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * This file is part of VirtualBox Open Source Edition (OSE), as
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * available from http://www.virtualbox.org. This file is free software;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * you can redistribute it and/or modify it under the terms of the GNU
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * General Public License as published by the Free Software Foundation,
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * distribution. VirtualBox OSE is distributed in the hope that it will
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * be useful, but WITHOUT ANY WARRANTY of any kind.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb/*******************************************************************************
7b59d02d2a384be9a08087b14defadd214b3c1ddjb* Header Files *
7b59d02d2a384be9a08087b14defadd214b3c1ddjb*******************************************************************************/
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include "the-nt-kernel.h"
7b59d02d2a384be9a08087b14defadd214b3c1ddjb/*******************************************************************************
7b59d02d2a384be9a08087b14defadd214b3c1ddjb* Defined Constants And Macros *
7b59d02d2a384be9a08087b14defadd214b3c1ddjb*******************************************************************************/
7b59d02d2a384be9a08087b14defadd214b3c1ddjb/** Maximum number of bytes we try to lock down in one go.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * This is supposed to have a limit right below 256MB, but this appears
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * to actually be much lower. The values here have been determined experimentally.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb/*******************************************************************************
7b59d02d2a384be9a08087b14defadd214b3c1ddjb* Structures and Typedefs *
7b59d02d2a384be9a08087b14defadd214b3c1ddjb*******************************************************************************/
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * The NT version of the memory object structure.
7b59d02d2a384be9a08087b14defadd214b3c1ddjbtypedef struct RTR0MEMOBJNT
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /** The core structure. */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /** Used MmAllocatePagesForMdl(). */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /** The number of PMDLs (memory descriptor lists) in the array. */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /** Array of MDL pointers. (variable size) */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * Deal with it on a per type basis (just as a variation).
7b59d02d2a384be9a08087b14defadd214b3c1ddjb Assert(pMemNt->Core.pv && pMemNt->cMdls == 1 && pMemNt->apMdls[0]);
8d7e41661dc4633488e93b13363137523ce59977jose borrego MmUnmapLockedPages(pMemNt->Core.pv, pMemNt->apMdls[0]);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States break;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb/* if (pMemNt->Core.u.ResVirt.R0Process == NIL_RTR0PROCESS)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PRTR0MEMOBJNT pMemNtParent = (PRTR0MEMOBJNT)pMemNt->Core.uRel.Child.pParent;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb Assert(pMemNtParent->cMdls == 1 && pMemNtParent->apMdls[0]);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb Assert( pMemNt->Core.u.Mapping.R0Process == NIL_RTR0PROCESS
7b59d02d2a384be9a08087b14defadd214b3c1ddjb || pMemNt->Core.u.Mapping.R0Process == RTR0ProcHandleSelf());
7b59d02d2a384be9a08087b14defadd214b3c1ddjb MmUnmapLockedPages(pMemNt->Core.pv, pMemNtParent->apMdls[0]);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb Assert( pMemNtParent->Core.enmType == RTR0MEMOBJTYPE_PHYS
7b59d02d2a384be9a08087b14defadd214b3c1ddjb Assert(pMemNt->Core.u.Mapping.R0Process == NIL_RTR0PROCESS);
7b59d02d2a384be9a08087b14defadd214b3c1ddjbint rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb AssertMsgReturn(cb <= _1G, ("%#x\n", cb), VERR_OUT_OF_RANGE); /* for safe size_t -> ULONG */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * Try allocate the memory and create an MDL for them so
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * we can query the physical addresses and do mappings later
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * without running into out-of-memory conditions and similar problems.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb void *pv = ExAllocatePoolWithTag(NonPagedPool, cb, IPRT_NT_POOL_TAG);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PMDL pMdl = IoAllocateMdl(pv, (ULONG)cb, FALSE, FALSE, NULL);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /*
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * Create the IPRT memory object.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)rtR0MemObjNew(sizeof(*pMemNt), RTR0MEMOBJTYPE_PAGE, pv, cb);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States pMemNt->apMdls[0] = pMdl;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
7b59d02d2a384be9a08087b14defadd214b3c1ddjbint rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb AssertMsgReturn(cb <= _1G, ("%#x\n", cb), VERR_OUT_OF_RANGE); /* for safe size_t -> ULONG */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * Try see if we get lucky first...
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * (We could probably just assume we're lucky on NT4.)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb int rc = rtR0MemObjNativeAllocPage(ppMem, cb, fExecutable);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb while (iPage-- > 0)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (rtR0MemObjNativeGetPagePhysAddr(*ppMem, iPage) >= _4G)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States rc = VERR_NO_MEMORY;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States break;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /* The following ASSUMES that rtR0MemObjNativeAllocPage returns a completed object. */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * Use MmAllocatePagesForMdl to specify the range of physical addresses we wish to use.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PMDL pMdl = MmAllocatePagesForMdl(Zero, HighAddr, Zero, cb);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (MmGetMdlByteCount(pMdl) >= cb)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States __try
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States {
7b59d02d2a384be9a08087b14defadd214b3c1ddjb void *pv = MmMapLockedPagesSpecifyCache(pMdl, KernelMode, MmCached, NULL /* no base address */,
7b59d02d2a384be9a08087b14defadd214b3c1ddjb FALSE /* no bug check on failure */, NormalPagePriority);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)rtR0MemObjNew(sizeof(*pMemNt), RTR0MEMOBJTYPE_LOW, pv, cb);
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright /* nothing */
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright#endif /* !IPRT_TARGET_NT4 */
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * Fall back on contiguous memory...
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright return rtR0MemObjNativeAllocCont(ppMem, cb, fExecutable);
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * Internal worker for rtR0MemObjNativeAllocCont(), rtR0MemObjNativeAllocPhys()
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * and rtR0MemObjNativeAllocPhysNC() that takes a max physical address in addition
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * to what rtR0MemObjNativeAllocCont() does.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @returns IPRT status code.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param ppMem Where to store the pointer to the ring-0 memory object.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param cb The size.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param fExecutable Whether the mapping should be executable or not.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param PhysHighest The highest physical address for the pages in allocation.
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic int rtR0MemObjNativeAllocContEx(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable, RTHCPHYS PhysHighest)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb AssertMsgReturn(cb <= _1G, ("%#x\n", cb), VERR_OUT_OF_RANGE); /* for safe size_t -> ULONG */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * Allocate the memory and create an MDL for it.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb void *pv = MmAllocateContiguousMemory(cb, PhysAddrHighest);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PMDL pMdl = IoAllocateMdl(pv, (ULONG)cb, FALSE, FALSE, NULL);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States MmBuildMdlForNonPagedPool(pMdl);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)rtR0MemObjNew(sizeof(*pMemNt), RTR0MEMOBJTYPE_CONT, pv, cb);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb pMemNt->Core.u.Cont.Phys = (RTHCPHYS)*MmGetMdlPfnArray(pMdl) << PAGE_SHIFT;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return VINF_SUCCESS;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States IoFreeMdl(pMdl);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesint rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return rtR0MemObjNativeAllocContEx(ppMem, cb, fExecutable, _4G-1);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
7b59d02d2a384be9a08087b14defadd214b3c1ddjbint rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * Try and see if we're lucky and get a contiguous chunk from MmAllocatePagesForMdl.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * This is preferable to using MmAllocateContiguousMemory because there are
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * a few situations where the memory shouldn't be mapped, like for instance
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * VT-x control memory. Since these are rather small allocations (one or
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * two pages) MmAllocatePagesForMdl will probably be able to satisfy the
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * request.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * If the allocation is big, the chances are *probably* not very good. The
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * current limit is kind of random...
7b59d02d2a384be9a08087b14defadd214b3c1ddjb HighAddr.QuadPart = PhysHighest == NIL_RTHCPHYS ? MAXLONGLONG : PhysHighest;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PMDL pMdl = MmAllocatePagesForMdl(Zero, HighAddr, Zero, cb);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (pMdl)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States size_t iPage;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States break;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)rtR0MemObjNew(sizeof(*pMemNt), RTR0MEMOBJTYPE_PHYS, NULL, cb);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb pMemNt->Core.u.Phys.PhysBase = (RTHCPHYS)paPfns[0] << PAGE_SHIFT;
8d7e41661dc4633488e93b13363137523ce59977jose borrego#endif /* !IPRT_TARGET_NT4 */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return rtR0MemObjNativeAllocContEx(ppMem, cb, false, PhysHighest);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
7b59d02d2a384be9a08087b14defadd214b3c1ddjbint rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb HighAddr.QuadPart = PhysHighest == NIL_RTHCPHYS ? MAXLONGLONG : PhysHighest;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PMDL pMdl = MmAllocatePagesForMdl(Zero, HighAddr, Zero, cb);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (pMdl)
8d7e41661dc4633488e93b13363137523ce59977jose borrego PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)rtR0MemObjNew(sizeof(*pMemNt), RTR0MEMOBJTYPE_PHYS_NC, NULL, cb);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return VERR_NO_MEMORY;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego#else /* IPRT_TARGET_NT4 */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return VERR_NOT_SUPPORTED;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego#endif /* IPRT_TARGET_NT4 */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbint rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * Validate the address range and create a descriptor for it.
8d7e41661dc4633488e93b13363137523ce59977jose borrego * Create the IPRT memory object.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)rtR0MemObjNew(sizeof(*pMemNt), RTR0MEMOBJTYPE_PHYS, NULL, cb);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * Internal worker for locking down pages.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @return IPRT status code.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param ppMem Where to store the memory object pointer.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param pv First page.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param cb Number of bytes.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param Task The task \a pv and \a cb refers to.
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic int rtR0MemObjNtLock(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, RTR0PROCESS R0Process)
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * Calc the number of MDLs we need and allocate the memory object structure.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (cMdls >= UINT32_MAX)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)rtR0MemObjNew(RT_OFFSETOF(RTR0MEMOBJNT, apMdls[cMdls]),
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * Loop locking down the sub parts of the memory.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * Calc the Mdl size and allocate it.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (cbCur > MAX_LOCK_MEM_SIZE)
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego PMDL pMdl = IoAllocateMdl(pb, (ULONG)cbCur, FALSE, FALSE, NULL);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States rc = VERR_NO_MEMORY;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * Lock the pages.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States __try
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego MmProbeAndLockPages(pMdl, R0Process == NIL_RTR0PROCESS ? KernelMode : UserMode, IoModifyAccess);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States {
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /* next */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States cbTotal += cbCur;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * We failed, perform cleanups.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb while (iMdl-- > 0)
7b59d02d2a384be9a08087b14defadd214b3c1ddjbint rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, RTR0PROCESS R0Process)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /* (Can use MmProbeAndLockProcessPages if we need to mess with other processes later.) */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return rtR0MemObjNtLock(ppMem, (void *)R3Ptr, cb, R0Process);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
7b59d02d2a384be9a08087b14defadd214b3c1ddjbint rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb)
7b59d02d2a384be9a08087b14defadd214b3c1ddjbint rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * MmCreateSection(SEC_RESERVE) + MmMapViewInSystemSpace perhaps?
7b59d02d2a384be9a08087b14defadd214b3c1ddjbint rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * ZeCreateSection(SEC_RESERVE) + ZwMapViewOfSection perhaps?
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * Internal worker for rtR0MemObjNativeMapKernel and rtR0MemObjNativeMapUser.
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * @returns IPRT status code.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param ppMem Where to store the memory object for the mapping.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param pMemToMap The memory object to map.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param pvFixed Where to map it. (void *)-1 if anywhere is fine.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param uAlignment The alignment requirement for the mapping.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param fProt The desired page protection for the mapping.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * @param R0Process If NIL_RTR0PROCESS map into system (kernel) memory.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * If not nil, it's the current process.
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic int rtR0MemObjNtMap(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * There are two basic cases here, either we've got an MDL and can
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * map it using MmMapLockedPages, or we've got a contiguous physical
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * range (MMIO most likely) and can use MmMapIoSpace.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /* don't attempt map locked regions with more than one mdl. */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /* we can't map anything to the first page, sorry. */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (pvFixed == 0)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /* only one system mapping for now - no time to figure out MDL restrictions right now. */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /** @todo uAlignment */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /** @todo How to set the protection on the pages? */
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego void *pv = MmMapLockedPagesSpecifyCache(pMemNtToMap->apMdls[0],
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States NOREF(fProt);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)rtR0MemObjNew(sizeof(*pMemNt), RTR0MEMOBJTYPE_MAPPING, pv,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return VINF_SUCCESS;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego MmUnmapLockedPages(pv, pMemNtToMap->apMdls[0]);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego /* nothing */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States rc = VERR_MAP_FAILED;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego AssertReturn( pMemNtToMap->Core.enmType == RTR0MEMOBJTYPE_PHYS
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego && !pMemNtToMap->Core.u.Phys.fAllocated, VERR_INTERNAL_ERROR);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego /* cannot map phys mem to user space (yet). */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb /** @todo uAlignment */
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego /** @todo How to set the protection on the pages? */
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego Phys.QuadPart = pMemNtToMap->Core.u.Phys.PhysBase;
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego void *pv = MmMapIoSpace(Phys, pMemNtToMap->Core.cb, MmCached); /** @todo add cache type to fProt. */
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego PRTR0MEMOBJNT pMemNt = (PRTR0MEMOBJNT)rtR0MemObjNew(sizeof(*pMemNt), RTR0MEMOBJTYPE_MAPPING, pv,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States pMemNt->Core.u.Mapping.R0Process = R0Process;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesint rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment, unsigned fProt)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return rtR0MemObjNtMap(ppMem, pMemToMap, pvFixed, uAlignment, fProt, NIL_RTR0PROCESS);
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoint rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb AssertReturn(R0Process == RTR0ProcHandleSelf(), VERR_NOT_SUPPORTED);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return rtR0MemObjNtMap(ppMem, pMemToMap, (void *)R3PtrFixed, uAlignment, fProt, R0Process);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
7f667e74610492ddbce8ce60f52ece95d2401949jose borregoRTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego PPFN_NUMBER paPfns = MmGetMdlPfnArray(pMemNt->apMdls[0]);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego size_t iMdl = iPage / (MAX_LOCK_MEM_SIZE >> PAGE_SHIFT);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego size_t iMdlPfn = iPage % (MAX_LOCK_MEM_SIZE >> PAGE_SHIFT);
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego PPFN_NUMBER paPfns = MmGetMdlPfnArray(pMemNt->apMdls[iMdl]);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return rtR0MemObjNativeGetPagePhysAddr(pMemNt->Core.uRel.Child.pParent, iPage);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return pMemNt->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States case RTR0MEMOBJTYPE_CONT: