MM.cpp revision a5c3cd5df26f544018e48530e8392f32c1aa12c8
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * MM - Memory Manager.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * available from http://www.virtualbox.org. This file is free software;
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * General Public License (GPL) as published by the Free Software
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * additional information or have any questions.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync/** @page pg_mm MM - The Memory Manager
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * The memory manager is in charge of the following memory:
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * - Hypervisor Memory Area (HMA) - Address space management.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * - Hypervisor Heap - A memory heap that lives in all contexts.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * - Tagged ring-3 heap.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * - Page pools - Primarily used by PGM for shadow page tables.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * - Locked process memory - Guest RAM and other. (reduce/obsolete this)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * - Physical guest memory (RAM & ROM) - Moving to PGM. (obsolete this)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * The global memory manager (GMM) is the global counter part / partner of MM.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * MM will provide therefore ring-3 callable interfaces for some of the GMM APIs
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * related to resource tracking (PGM is the user).
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @see grp_mm
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @section sec_mm_hma Hypervisor Memory Area
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * The HMA is used when executing in raw-mode. We borrow, with the help of
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * PGMMap, some unused space (one or more page directory entries to be precise)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * in the guest's virtual memory context. PGM will monitor the guest's virtual
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * address space for changes and relocate the HMA when required.
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * To give some idea what's in the HMA, study the 'info hma' output:
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync * @verbatim
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncVBoxDbg> info hma
deb4998ba50060c48cce222fd18a8eed053918d7vboxsyncHypervisor Memory Area (HMA) Layout: Base 00000000a0000000, 0x00800000 bytes
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a05cc000-00000000a05cd000 DYNAMIC fence
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a05c4000-00000000a05cc000 DYNAMIC Dynamic mapping
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a05c3000-00000000a05c4000 DYNAMIC fence
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a05b8000-00000000a05c3000 DYNAMIC Paging
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a05b6000-00000000a05b8000 MMIO2 0000000000000000 PCNetShMem
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a0536000-00000000a05b6000 MMIO2 0000000000000000 VGA VRam
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a0523000-00000000a0536000 00002aaab3d0c000 LOCKED autofree alloc once (PDM_DEVICE)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a0522000-00000000a0523000 DYNAMIC fence
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a051e000-00000000a0522000 00002aaab36f5000 LOCKED autofree VBoxDD2GC.gc
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a051d000-00000000a051e000 DYNAMIC fence
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a04eb000-00000000a051d000 00002aaab36c3000 LOCKED autofree VBoxDDGC.gc
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a04ea000-00000000a04eb000 DYNAMIC fence
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a04e9000-00000000a04ea000 00002aaab36c2000 LOCKED autofree ram range (High ROM Region)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a04e8000-00000000a04e9000 DYNAMIC fence
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a040e000-00000000a04e8000 00002aaab2e6d000 LOCKED autofree VMMGC.gc
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a0208000-00000000a040e000 00002aaab2c67000 LOCKED autofree alloc once (PATM)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a01f7000-00000000a0208000 00002aaaab92d000 LOCKED autofree alloc once (SELM)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a01e7000-00000000a01f7000 00002aaaab5e8000 LOCKED autofree alloc once (SELM)
deb4998ba50060c48cce222fd18a8eed053918d7vboxsync00000000a01e6000-00000000a01e7000 DYNAMIC fence
#include "MMInternal.h"
return rc;
return rc;
int rc;
if (!pMMCfg)
bool fPreAlloc;
fPreAlloc = false;
AssertMsgRCReturn(rc, ("Configuration error: Failed to query integer \"RamPreAlloc\", rc=%Rrc.\n", rc), rc);
cbRam = 0;
AssertMsgRCReturn(rc, ("Configuration error: Failed to query integer \"RamSize\", rc=%Rrc.\n", rc), rc);
AssertLogRelMsgRCReturn(rc, ("Configuration error: Failed to query integer \"RamHoleSize\", rc=%Rrc.\n", rc), rc);
Log(("MM: %RU64 bytes of RAM%s with a hole at %RU64 up to 4GB.\n", cbRam, fPreAlloc ? " (PreAlloc)" : "", offRamHole));
return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS, "Unknown \"MM/Policy\" value \"%s\"", sz);
AssertMsgRCReturn(rc, ("Configuration error: Failed to query string \"MM/Policy\", rc=%Rrc.\n", rc), rc);
return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS, "Unknown \"MM/Priority\" value \"%s\"", sz);
AssertMsgRCReturn(rc, ("Configuration error: Failed to query string \"MM/Priority\", rc=%Rrc.\n", rc), rc);
return VINF_SUCCESS;
#ifdef VBOX_WITH_NEW_PHYS_CODE
&& fPreAlloc)
#ifdef VBOX_WITH_NEW_PHYS_CODE
AssertMsg(pVM->mm.s.cBasePages == cBasePages || RT_FAILURE(rc), ("%RX64 != %RX64\n", pVM->mm.s.cBasePages, cBasePages));
return rc;
while (pLockedMem)
case MM_LOCKED_TYPE_HYPER:
case MM_LOCKED_TYPE_PHYS:
return VINF_SUCCESS;
#ifndef VBOX_WITH_NEW_PHYS_CODE
|| !u32Version)
int rc;
return rc;
LogRel(("mmR3Load: Memory configuration has changed. cPages=%#RX64 saved=%#RX64\n", pVM->mm.s.cBasePages, cPages));
return rc;
LogRel(("mmR3Load: Memory configuration has changed. cbRamBase=%#RX64 save=%#RX64\n", pVM->mm.s.cbRamBase, cb));
return rc;
return VINF_SUCCESS;
LogFlow(("MMR3IncreaseBaseReservation: +%RU64 (%RU64 -> %RU64\n", cAddBasePages, cOld, pVM->mm.s.cBasePages));
VMSetError(pVM, rc, RT_SRC_POS, N_("Failed to reserved physical memory for the RAM (%#RX64 -> %#RX64 + %#RX32)"),
return rc;
LogFlow(("MMR3ReserveHandyPages: %RU32 (base %RU64)\n", pVM->mm.s.cHandyPages, pVM->mm.s.cBasePages));
VMSetError(pVM, rc, RT_SRC_POS, N_("Failed to reserved physical memory for the RAM (%#RX64 + %#RX32)"),
return rc;
LogFlow(("MMR3AdjustFixedReservation: %d (%u -> %u)\n", cDeltaFixedPages, cOld, pVM->mm.s.cFixedPages));
return rc;
VMSetError(pVM, rc, RT_SRC_POS, N_("Failed to reserve physical memory for shadow page tables (%#x -> %#x)"), cOld, pVM->mm.s.cShadowPages);
return rc;
int mmR3LockMem(PVM pVM, void *pv, size_t cb, MMLOCKEDTYPE eType, PMMLOCKEDMEM *ppLockedMem, bool fSilentFailure)
if (ppLockedMem)
PMMLOCKEDMEM pLockedMem = (PMMLOCKEDMEM)MMR3HeapAlloc(pVM, MM_TAG_MM, RT_OFFSETOF(MMLOCKEDMEM, aPhysPages[cPages]));
if (!pLockedMem)
return VERR_NO_MEMORY;
if (ppLockedMem)
if (!fSilentFailure)
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;
while (iPage-- > 0)
return VINF_SUCCESS;
return VERR_INVALID_POINTER;
return VERR_ACCESS_DENIED;