MM.cpp revision c70e869b25e3a509d5736625aba090331dd26d9d
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * MM - Memory Monitor(/Manager).
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2006 InnoTek Systemberatung GmbH
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * available from http://www.virtualbox.org. This file is free software;
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * General Public License as published by the Free Software Foundation,
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * If you received this file as part of a commercial VirtualBox
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * distribution, then only the terms of your commercial VirtualBox
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * license agreement apply instead of the previous paragraph.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync/** @page pg_mm MM - The Memory Monitor/Manager
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * It seems like this is going to be the entity taking care of memory allocations
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * and the locking of physical memory for a VM. MM will track these allocations and
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * pinnings so pointer conversions, memory read and write, and correct clean up can
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * Memory types:
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * - Hypervisor Memory Area (HMA).
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * - Page tables.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * - Physical pages.
468c2bcb36eb9a032f5dd0fcb34db10bd58e9996vboxsync * The first two types are not accessible using the generic conversion functions
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * for GC memory, there are special functions for these.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * A decent structure for this component need to be eveloped as we see usage. One
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * or two rewrites is probabaly needed to get it right...
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * @section Hypervisor Memory Area
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * The hypervisor is give 4MB of space inside the guest, we assume that we can
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * steal an page directory entry from the guest OS without cause trouble. In
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * addition to these 4MB we'll be mapping memory for the graphics emulation,
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * but that will be an independant mapping.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * The 4MBs are divided into two main parts:
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * -# The static code and data
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * -# The shortlived page mappings.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * The first part is used for the VM structure, the core code (VMMSwitch),
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * GC modules, and the alloc-only-heap. The size will be determined at a
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * later point but initially we'll say 2MB of locked memory, most of which
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * is non contiguous physically.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * The second part is used for mapping pages to the hypervisor. We'll be using
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * a simple round robin when doing these mappings. This means that no-one can
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * assume that a mapping hangs around for very long, while the managing of the
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * pages are very simple.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * @section Page Pool
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * The MM manages a per VM page pool from which other components can allocate
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * locked, page aligned and page granular memory objects. The pool provides
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * facilities to convert back and forth between physical and virtual addresses
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * (within the pool of course). Several specialized interfaces are provided
65697a26b524640b83828b715160c798c43a0424vboxsync * for the most common alloctions and convertions to save the caller from
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * bothersome casting and extra parameter passing.
65697a26b524640b83828b715160c798c43a0424vboxsync/*******************************************************************************
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync* Header Files *
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync*******************************************************************************/
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync/*******************************************************************************
26947320577c481b4afefdb0afbb855181e5b2e8vboxsync* Internal Functions *
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync*******************************************************************************/
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsyncstatic DECLCALLBACK(int) mmR3Save(PVM pVM, PSSMHANDLE pSSM);
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsyncstatic DECLCALLBACK(int) mmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t u32Version);
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * Initializes the MM.
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * MM is managing the virtual address space (among other things) and
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * setup the hypvervisor memory area mapping in the VM structure and
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * the hypvervisor alloc-only-heap. Assuming the current init order
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * and components the hypvervisor memory area looks like this:
a4ba1fc5788b1fb4c078587d5f55936e1b83098dvboxsync * -# VM Structure.
return rc;
return rc;
return rc;
cbRam = 0;
return VINF_SUCCESS;
#ifdef PGM_DYNAMIC_RAM_ALLOC
rc = MMR3PhysRegister(pVM, pVM->mm.s.pvRamBaseHC, 0, pVM->mm.s.cbRamBase, MM_RAM_FLAGS_DYNAMIC_ALLOC, "Main Memory");
return rc;
return rc;
return rc;
while (pLockedMem)
case MM_LOCKED_TYPE_PHYS:
case MM_LOCKED_TYPE_HYPER:
if (!fKeepTheHeap)
return rc;
Log(("mmR3Load: Memory configuration has changed. cbRAMSize=%#x save %#x\n", pVM->mm.s.cbRAMSize, cb));
return rc;
Log(("mmR3Load: Memory configuration has changed. cbRamBase=%#x save %#x\n", pVM->mm.s.cbRamBase, cb));
return rc;
if (ppLockedMem)
PMMLOCKEDMEM pLockedMem = (PMMLOCKEDMEM)MMR3HeapAlloc(pVM, MM_TAG_MM, RT_OFFSETOF(MMLOCKEDMEM, aPhysPages[cPages]));
if (!pLockedMem)
return VERR_NO_MEMORY;
if (ppLockedMem)
rc = VMSetError(pVM, rc, RT_SRC_POS, N_("Failed to lock %d bytes of host memory (out of memory)"), cb);
return rc;
int mmr3MapLocked(PVM pVM, PMMLOCKEDMEM pLockedMem, RTGCPTR Addr, unsigned iPage, size_t cPages, unsigned fFlags)
AssertMsg(iPage < (pLockedMem->cb >> PAGE_SHIFT), ("never even think about giving me a bad iPage(=%d)\n", iPage));
AssertMsg(iPage + cPages <= (pLockedMem->cb >> PAGE_SHIFT), ("never even think about giving me a bad cPages(=%d)\n", cPages));
while (cPages)
return rc;
cPages--;
iPage++;
pPhysPage++;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
while (iPage-- > 0)
return VINF_SUCCESS;
return VERR_INVALID_POINTER;
return VERR_ACCESS_DENIED;