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