memobj-r0drv.cpp revision e5bfc5c34142a7550be3564a8e01a037b1db5b31
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * innotek Portable Runtime - Ring-0 Memory Objects, Common Code.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Copyright (C) 2006-2007 innotek GmbH
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * General Public License as published by the Free Software Foundation,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync* Header Files *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#define LOG_GROUP RTLOGGROUP_DEFAULT ///@todo RTLOGGROUP_MEM
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Internal function for allocating a new memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns The allocated and initialized handle.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param cbSelf The size of the memory object handle. 0 mean default size.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param enmType The memory object type.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param pv The memory object mapping.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param cb The size of the memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncPRTR0MEMOBJINTERNAL rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *pv, size_t cb)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* validate the size */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Allocate and initialize the object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Deletes an incomplete memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This is for cleaning up after failures during object creation.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param pMem The incomplete memory object to delete.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Links a mapping object to a primary object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns IPRT status code.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @retval VINF_SUCCESS on success.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @retval VINF_NO_MEMORY if we couldn't expand the mapping array of the parent.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param pParent The parent (primary) memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param pChild The child (mapping) memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic int rtR0MemObjLink(PRTR0MEMOBJINTERNAL pParent, PRTR0MEMOBJINTERNAL pChild)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* sanity */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* expand the array? */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync void *pv = RTMemRealloc(pParent->uRel.Parent.papMappings,
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync (i + 32) * sizeof(pParent->uRel.Parent.papMappings[0]));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pParent->uRel.Parent.papMappings = (PPRTR0MEMOBJINTERNAL)pv;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* do the linking. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Checks if this is mapping or not.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns true if it's a mapping, otherwise false.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param MemObj The ring-0 memory object handle.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncRTR0DECL(bool) RTR0MemObjIsMapping(RTR0MEMOBJ MemObj)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Validate the object handle. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PRTR0MEMOBJINTERNAL pMem = (PRTR0MEMOBJINTERNAL)MemObj;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), false);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), false);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* hand it on to the inlined worker. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Gets the address of a ring-0 memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns The address of the memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns NULL if the handle is invalid (asserts in strict builds) or if there isn't any mapping.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param MemObj The ring-0 memory object handle.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncRTR0DECL(void *) RTR0MemObjAddress(RTR0MEMOBJ MemObj)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Validate the object handle. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PRTR0MEMOBJINTERNAL pMem = (PRTR0MEMOBJINTERNAL)MemObj;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* return the mapping address. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Gets the ring-3 address of a ring-0 memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This only applies to ring-0 memory object with ring-3 mappings of some kind, i.e.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * locked user memory, reserved user address space and user mappings. This API should
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * not be used on any other objects.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns The address of the memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns NULL if the handle is invalid or if it's not an object with a ring-3 mapping.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Strict builds will assert in both cases.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param MemObj The ring-0 memory object handle.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncRTR0DECL(RTR3PTR) RTR0MemObjAddressR3(RTR0MEMOBJ MemObj)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Validate the object handle. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PRTR0MEMOBJINTERNAL pMem = (PRTR0MEMOBJINTERNAL)MemObj;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), NIL_RTR3PTR);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), NIL_RTR3PTR);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn( ( pMem->enmType == RTR0MEMOBJTYPE_MAPPING
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* return the mapping address. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Gets the size of a ring-0 memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns The address of the memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns NULL if the handle is invalid (asserts in strict builds) or if there isn't any mapping.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param MemObj The ring-0 memory object handle.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Validate the object handle. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PRTR0MEMOBJINTERNAL pMem = (PRTR0MEMOBJINTERNAL)MemObj;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), 0);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* return the size. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Get the physical address of an page in the memory object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns The physical address.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns NIL_RTHCPHYS if the object doesn't contain fixed physical pages.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns NIL_RTHCPHYS if the iPage is out of range.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @returns NIL_RTHCPHYS if the object handle isn't valid.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param MemObj The ring-0 memory object handle.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * @param iPage The page number within the object.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncRTR0DECL(RTHCPHYS) RTR0MemObjGetPagePhysAddr(RTR0MEMOBJ MemObj, size_t iPage)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Validate the object handle. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync PRTR0MEMOBJINTERNAL pMem = (PRTR0MEMOBJINTERNAL)MemObj;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, NIL_RTHCPHYS);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, NIL_RTHCPHYS);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), NIL_RTHCPHYS);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), NIL_RTHCPHYS);
return NIL_RTHCPHYS;
return VINF_SUCCESS;
AssertReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, VERR_INVALID_HANDLE);
if (!fFreeMappings)
return VERR_MEMORY_BUSY;
Log(("RTR0MemObjFree: failed to free mapping %p: %p %#zx; rc=%Vrc\n", pChild, pChild->pv, pChild->cb, rc));
return rc;
pParent->uRel.Parent.papMappings[i] = pParent->uRel.Parent.papMappings[--pParent->uRel.Parent.cMappings];
return rc;
* @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
* @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
* @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
RTR0DECL(int) RTR0MemObjReserveKernel(PRTR0MEMOBJ pMemObj, void *pvFixed, size_t cb, size_t uAlignment)
if (uAlignment == 0)
AssertReturn(uAlignment == PAGE_SIZE || uAlignment == _2M || uAlignment == _4M, VERR_INVALID_PARAMETER);
* @param R0Process The process to reserve the memory in. NIL_R0PROCESS is an alias for the current one.
RTR0DECL(int) RTR0MemObjReserveUser(PRTR0MEMOBJ pMemObj, void *pvFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
if (uAlignment == 0)
AssertReturn(uAlignment == PAGE_SIZE || uAlignment == _2M || uAlignment == _4M, VERR_INVALID_PARAMETER);
RTR0DECL(int) RTR0MemObjMapKernel(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment, unsigned fProt)
AssertReturn(pMemToMap->enmType > RTR0MEMOBJTYPE_INVALID && pMemToMap->enmType < RTR0MEMOBJTYPE_END, VERR_INVALID_HANDLE);
if (uAlignment == 0)
AssertReturn(uAlignment == PAGE_SIZE || uAlignment == _2M || uAlignment == _4M, VERR_INVALID_PARAMETER);
AssertReturn(!(fProt & ~(RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC)), VERR_INVALID_PARAMETER);
return rc;
* @param R0Process The process to map the memory into. NIL_R0PROCESS is an alias for the current one.
RTR0DECL(int) RTR0MemObjMapUser(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
AssertReturn(pMemToMap->enmType > RTR0MEMOBJTYPE_INVALID && pMemToMap->enmType < RTR0MEMOBJTYPE_END, VERR_INVALID_HANDLE);
if (uAlignment == 0)
AssertReturn(uAlignment == PAGE_SIZE || uAlignment == _2M || uAlignment == _4M, VERR_INVALID_PARAMETER);
AssertReturn(!(fProt & ~(RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC)), VERR_INVALID_PARAMETER);
return rc;