PGMShw.h revision d099ccfb66d26601f93e7967e8e73cee4b9c62df
54a2dc8050116a473e8644b8d096dd99fcee1ec5vboxsync * VBox - Page Manager / Monitor, Shadow Paging Template.
c76aa9ecac0d701ddd7939c9be92469ea1d1bd95vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
c76aa9ecac0d701ddd7939c9be92469ea1d1bd95vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c76aa9ecac0d701ddd7939c9be92469ea1d1bd95vboxsync * available from http://www.virtualbox.org. This file is free software;
c76aa9ecac0d701ddd7939c9be92469ea1d1bd95vboxsync * you can redistribute it and/or modify it under the terms of the GNU
c76aa9ecac0d701ddd7939c9be92469ea1d1bd95vboxsync * General Public License (GPL) as published by the Free Software
6898070acb4aa64f0a0f79deb1825578504f70c4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
6898070acb4aa64f0a0f79deb1825578504f70c4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
6898070acb4aa64f0a0f79deb1825578504f70c4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
6898070acb4aa64f0a0f79deb1825578504f70c4vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
6898070acb4aa64f0a0f79deb1825578504f70c4vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
183bc517a9dca5a54ba6701581066363e78de360vboxsync * additional information or have any questions.
183bc517a9dca5a54ba6701581066363e78de360vboxsync/*******************************************************************************
183bc517a9dca5a54ba6701581066363e78de360vboxsync* Defined Constants And Macros *
183bc517a9dca5a54ba6701581066363e78de360vboxsync*******************************************************************************/
534226d9c71bac7817fbcfeace5cf548084d7f6cvboxsync# define SHW_TOTAL_PD_ENTRIES (EPT_PG_AMD64_ENTRIES*EPT_PG_AMD64_PDPE_ENTRIES)
534226d9c71bac7817fbcfeace5cf548084d7f6cvboxsync# define SHW_POOL_ROOT_IDX PGMPOOL_IDX_NESTED_ROOT /* do not use! exception is real mode & protected mode without paging. */
f5840fca26963de38533fd43c951758c386ed60avboxsync# define SHW_TOTAL_PD_ENTRIES (X86_PG_AMD64_ENTRIES*X86_PG_AMD64_PDPE_ENTRIES)
f5840fca26963de38533fd43c951758c386ed60avboxsync# else /* 32 bits PAE mode */
1400154bf298b7208c611e81321e0c82b721afd7vboxsync# define SHW_TOTAL_PD_ENTRIES (X86_PG_PAE_ENTRIES*X86_PG_PAE_PDPE_ENTRIES)
af66a95ff0d75da2d50719eb14a686a9de7bff76vboxsync/*******************************************************************************
af66a95ff0d75da2d50719eb14a686a9de7bff76vboxsync* Internal Functions *
af66a95ff0d75da2d50719eb14a686a9de7bff76vboxsync*******************************************************************************/
8d56e4d4be56ac2cbe2c03ce678432c6d8d1d7d3vboxsyncPGM_SHW_DECL(int, InitData)(PVM pVM, PPGMMODEDATA pModeData, bool fResolveGCAndR0);
8d56e4d4be56ac2cbe2c03ce678432c6d8d1d7d3vboxsyncPGM_SHW_DECL(int, Enter)(PVMCPU pVCpu, bool fIs64BitsPagingMode);
8d56e4d4be56ac2cbe2c03ce678432c6d8d1d7d3vboxsyncPGM_SHW_DECL(int, Relocate)(PVMCPU pVCpu, RTGCPTR offDelta);
5a1e64cee1eec57da3361ccda90351bd9c2e97a6vboxsyncPGM_SHW_DECL(int, GetPage)(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys);
5a1e64cee1eec57da3361ccda90351bd9c2e97a6vboxsyncPGM_SHW_DECL(int, ModifyPage)(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
fdb7d72fbf00de23e58088243b932f48684e83davboxsync * Initializes the guest bit of the paging mode data.
fdb7d72fbf00de23e58088243b932f48684e83davboxsync * @returns VBox status code.
fdb7d72fbf00de23e58088243b932f48684e83davboxsync * @param pVM The VM handle.
fdb7d72fbf00de23e58088243b932f48684e83davboxsync * @param fResolveGCAndR0 Indicate whether or not GC and Ring-0 symbols can be resolved now.
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync * This is used early in the init process to avoid trouble with PDM
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync * not being initialized yet.
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsyncPGM_SHW_DECL(int, InitData)(PVM pVM, PPGMMODEDATA pModeData, bool fResolveGCAndR0)
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync Assert(pModeData->uShwType == PGM_SHW_TYPE || pModeData->uShwType == PGM_TYPE_NESTED);
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync /* Ring-3 */
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync pModeData->pfnR3ShwRelocate = PGM_SHW_NAME(Relocate);
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync pModeData->pfnR3ShwGetPage = PGM_SHW_NAME(GetPage);
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync pModeData->pfnR3ShwModifyPage = PGM_SHW_NAME(ModifyPage);
e5ece1e2eda83c3ac47fc02dc4d343e430009381vboxsync#if PGM_SHW_TYPE != PGM_TYPE_AMD64 && PGM_SHW_TYPE != PGM_TYPE_NESTED && PGM_SHW_TYPE != PGM_TYPE_EPT /* No AMD64 for traditional virtualization, only VT-x and AMD-V. */
b9966c0aebbaadea7fafdb13bd9cc7dec1dde6e2vboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_SHW_NAME_RC_STR(GetPage), &pModeData->pfnRCShwGetPage);
b9966c0aebbaadea7fafdb13bd9cc7dec1dde6e2vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_SHW_NAME_RC_STR(GetPage), rc), rc);
b9966c0aebbaadea7fafdb13bd9cc7dec1dde6e2vboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_SHW_NAME_RC_STR(ModifyPage), &pModeData->pfnRCShwModifyPage);
b9966c0aebbaadea7fafdb13bd9cc7dec1dde6e2vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_SHW_NAME_RC_STR(ModifyPage), rc), rc);
b9966c0aebbaadea7fafdb13bd9cc7dec1dde6e2vboxsync#endif /* Not AMD64 shadow paging. */
5db64e99b90067bcff9b0c080746edf83cf9dae6vboxsync /* Ring-0 */
5db64e99b90067bcff9b0c080746edf83cf9dae6vboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_SHW_NAME_R0_STR(GetPage), &pModeData->pfnR0ShwGetPage);
5db64e99b90067bcff9b0c080746edf83cf9dae6vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_SHW_NAME_R0_STR(GetPage), rc), rc);
5db64e99b90067bcff9b0c080746edf83cf9dae6vboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_SHW_NAME_R0_STR(ModifyPage), &pModeData->pfnR0ShwModifyPage);
5db64e99b90067bcff9b0c080746edf83cf9dae6vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_SHW_NAME_R0_STR(ModifyPage), rc), rc);
fae3aa27fee8a48462bbdb535cc8674f66249f6bvboxsync * Enters the shadow mode.
02ab40eecbb0eb6b6cf6101439e1b2c40ff169d2vboxsync * @returns VBox status code.
02ab40eecbb0eb6b6cf6101439e1b2c40ff169d2vboxsync * @param pVCpu The VMCPU to operate on.
02ab40eecbb0eb6b6cf6101439e1b2c40ff169d2vboxsync * @param fIs64BitsPagingMode New shadow paging mode is for 64 bits? (only relevant for 64 bits guests on a 32 bits AMD-V nested paging host)
02ab40eecbb0eb6b6cf6101439e1b2c40ff169d2vboxsyncPGM_SHW_DECL(int, Enter)(PVMCPU pVCpu, bool fIs64BitsPagingMode)
a4b0396828d3dfafb72e49a456c926b62bd19fb4vboxsync#if PGM_SHW_TYPE == PGM_TYPE_NESTED || PGM_SHW_TYPE == PGM_TYPE_EPT
a4b0396828d3dfafb72e49a456c926b62bd19fb4vboxsync# if PGM_SHW_TYPE == PGM_TYPE_NESTED && HC_ARCH_BITS == 32
a4b0396828d3dfafb72e49a456c926b62bd19fb4vboxsync /* Must distinguish between 32 and 64 bits guest paging modes as we'll use a different shadow paging root/mode in both cases. */
a4b0396828d3dfafb72e49a456c926b62bd19fb4vboxsync RTGCPHYS GCPhysCR3 = (fIs64BitsPagingMode) ? RT_BIT_64(63) : RT_BIT_64(62);
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync int rc = pgmPoolAlloc(pVM, GCPhysCR3, PGMPOOLKIND_ROOT_NESTED, PGMPOOL_IDX_NESTED_ROOT, GCPhysCR3 >> PAGE_SHIFT, &pNewShwPageCR3, true /* lock page */);
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync pVCpu->pgm.s.iShwUserTable = GCPhysCR3 >> PAGE_SHIFT;
1c65c68707cffcad0ea498eba4da76fa07bf2d6cvboxsync pVCpu->pgm.s.pShwPageCR3RC = MMHyperCCToRC(pVM, pVCpu->pgm.s.pShwPageCR3R3);
1c65c68707cffcad0ea498eba4da76fa07bf2d6cvboxsync pVCpu->pgm.s.pShwPageCR3R0 = MMHyperCCToR0(pVM, pVCpu->pgm.s.pShwPageCR3R3);
b511f3c653d106f51f22f5015f6a24cc6e1108d6vboxsync Log(("Enter nested shadow paging mode: root %RHv phys %RHp\n", pVCpu->pgm.s.pShwPageCR3R3, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3)->Core.Key));
73130ef6d5209630eb0e7baa07415cad1a7791dbvboxsync * Relocate any GC pointers related to shadow mode paging.
73130ef6d5209630eb0e7baa07415cad1a7791dbvboxsync * @returns VBox status code.
b511f3c653d106f51f22f5015f6a24cc6e1108d6vboxsync * @param pVCpu The VMCPU to operate on.
73130ef6d5209630eb0e7baa07415cad1a7791dbvboxsync * @param offDelta The reloation offset.
aa42629e12e555ed393a4e1a0580560de23f01f9vboxsyncPGM_SHW_DECL(int, Relocate)(PVMCPU pVCpu, RTGCPTR offDelta)
8f15b6c92cae9a259476b2e462522fe42851682bvboxsync * Exits the shadow mode.
8f15b6c92cae9a259476b2e462522fe42851682bvboxsync * @returns VBox status code.
3533947350580467c10357b0632723f8894c2470vboxsync * @param pVCpu The VMCPU to operate on.
2f039d2bda433dc9a6dc5aaa391bd7e1d3341989vboxsync if ( ( pVCpu->pgm.s.enmShadowMode == PGMMODE_NESTED
3bca454544ce3065366c6bf3cc297e3b4712cbc5vboxsync Assert(pVCpu->pgm.s.iShwUser == PGMPOOL_IDX_NESTED_ROOT);
3bca454544ce3065366c6bf3cc297e3b4712cbc5vboxsync /* Mark the page as unlocked; allow flushing again. */
3bca454544ce3065366c6bf3cc297e3b4712cbc5vboxsync pgmPoolUnlockPage(pPool, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3));