PGMBth.h revision 1e3576bc616045a5585190fcbc221648d17b23af
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* $Id$ */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VBox - Page Manager / Monitor, Shadow+Guest Paging Template.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync *
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * additional information or have any questions.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Internal Functions *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync__BEGIN_DECLS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, InitData)(PVM pVM, PPGMMODEDATA pModeData, bool fResolveGCAndR0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, Enter)(PVM pVM, RTGCPHYS GCPhysCR3);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, Relocate)(PVM pVM, RTGCPTR offDelta);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsyncPGM_BTH_DECL(int, Trap0eHandler)(PVM pVM, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, SyncCR3)(PVM pVM, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, SyncPage)(PVM pVM, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, VerifyAccessSyncPage)(PVM pVM, RTGCPTR Addr, unsigned fPage, unsigned uError);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, InvalidatePage)(PVM pVM, RTGCPTR GCPtrPage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, PrefetchPage)(PVM pVM, RTGCPTR GCPtrPage);
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsyncPGM_BTH_DECL(unsigned, AssertCR3)(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr = 0, RTGCPTR cb = ~(RTGCPTR)0);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, MapCR3)(PVM pVM, RTGCPHYS GCPhysCR3);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, UnmapCR3)(PVM pVM);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync__END_DECLS
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Initializes the both bit of the paging mode data.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM The VM handle.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param fResolveGCAndR0 Indicate whether or not GC and Ring-0 symbols can be resolved now.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This is used early in the init process to avoid trouble with PDM
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * not being initialized yet.
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync */
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsyncPGM_BTH_DECL(int, InitData)(PVM pVM, PPGMMODEDATA pModeData, bool fResolveGCAndR0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pModeData->uShwType == PGM_SHW_TYPE); Assert(pModeData->uGstType == PGM_GST_TYPE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Ring 3 */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pModeData->pfnR3BthRelocate = PGM_BTH_NAME(Relocate);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pModeData->pfnR3BthSyncCR3 = PGM_BTH_NAME(SyncCR3);
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync pModeData->pfnR3BthInvalidatePage = PGM_BTH_NAME(InvalidatePage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pModeData->pfnR3BthSyncPage = PGM_BTH_NAME(SyncPage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pModeData->pfnR3BthPrefetchPage = PGM_BTH_NAME(PrefetchPage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pModeData->pfnR3BthVerifyAccessSyncPage = PGM_BTH_NAME(VerifyAccessSyncPage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_STRICT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pModeData->pfnR3BthAssertCR3 = PGM_BTH_NAME(AssertCR3);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pModeData->pfnR3BthMapCR3 = PGM_BTH_NAME(MapCR3);
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync pModeData->pfnR3BthUnmapCR3 = PGM_BTH_NAME(UnmapCR3);
2daaccf68be3773aee600c5c3e48bcf5401418a6vboxsync
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync if (fResolveGCAndR0)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#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. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* GC */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_BTH_NAME_RC_STR(Trap0eHandler), &pModeData->pfnRCBthTrap0eHandler);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_RC_STR(Trap0eHandler), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_BTH_NAME_RC_STR(InvalidatePage), &pModeData->pfnRCBthInvalidatePage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_RC_STR(InvalidatePage), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_BTH_NAME_RC_STR(SyncCR3), &pModeData->pfnRCBthSyncCR3);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_RC_STR(SyncPage), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_BTH_NAME_RC_STR(SyncPage), &pModeData->pfnRCBthSyncPage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_RC_STR(SyncPage), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_BTH_NAME_RC_STR(PrefetchPage), &pModeData->pfnRCBthPrefetchPage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_RC_STR(PrefetchPage), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_BTH_NAME_RC_STR(VerifyAccessSyncPage),&pModeData->pfnRCBthVerifyAccessSyncPage);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_RC_STR(VerifyAccessSyncPage), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# ifdef VBOX_STRICT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_BTH_NAME_RC_STR(AssertCR3), &pModeData->pfnRCBthAssertCR3);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_RC_STR(AssertCR3), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_BTH_NAME_RC_STR(MapCR3), &pModeData->pfnRCBthMapCR3);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_RC_STR(MapCR3), rc), rc);
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync rc = PDMR3LdrGetSymbolRC(pVM, NULL, PGM_BTH_NAME_RC_STR(UnmapCR3), &pModeData->pfnRCBthUnmapCR3);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_RC_STR(UnmapCR3), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* Not AMD64 shadow paging. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Ring 0 */
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_BTH_NAME_R0_STR(Trap0eHandler), &pModeData->pfnR0BthTrap0eHandler);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_R0_STR(Trap0eHandler), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_BTH_NAME_R0_STR(InvalidatePage), &pModeData->pfnR0BthInvalidatePage);
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_R0_STR(InvalidatePage), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_BTH_NAME_R0_STR(SyncCR3), &pModeData->pfnR0BthSyncCR3);
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_R0_STR(SyncCR3), rc), rc);
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_BTH_NAME_R0_STR(SyncPage), &pModeData->pfnR0BthSyncPage);
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_R0_STR(SyncPage), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_BTH_NAME_R0_STR(PrefetchPage), &pModeData->pfnR0BthPrefetchPage);
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_R0_STR(PrefetchPage), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_BTH_NAME_R0_STR(VerifyAccessSyncPage),&pModeData->pfnR0BthVerifyAccessSyncPage);
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_R0_STR(VerifyAccessSyncPage), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_STRICT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_BTH_NAME_R0_STR(AssertCR3), &pModeData->pfnR0BthAssertCR3);
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_R0_STR(AssertCR3), rc), rc);
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync#endif
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_BTH_NAME_R0_STR(MapCR3), &pModeData->pfnR0BthMapCR3);
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_R0_STR(MapCR3), rc), rc);
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync rc = PDMR3LdrGetSymbolR0(pVM, NULL, PGM_BTH_NAME_R0_STR(UnmapCR3), &pModeData->pfnR0BthUnmapCR3);
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync AssertMsgRCReturn(rc, ("%s -> rc=%Rrc\n", PGM_BTH_NAME_R0_STR(UnmapCR3), rc), rc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync/**
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync * Enters the shadow+guest mode.
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync *
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync * @returns VBox status code.
fdea543f71872a3ec3909536a4fce37ab7aa3a8bvboxsync * @param pVM VM handle.
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync * @param GCPhysCR3 The physical address from the CR3 register.
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync */
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsyncPGM_BTH_DECL(int, Enter)(PVM pVM, RTGCPHYS GCPhysCR3)
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Here we deal with allocation of the root shadow page table for real and protected mode during mode switches;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Other modes rely on MapCR3/UnmapCR3 to setup the shadow root page tables.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync# if ( ( PGM_SHW_TYPE == PGM_TYPE_32BITS \
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync || PGM_SHW_TYPE == PGM_TYPE_PAE \
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync || PGM_SHW_TYPE == PGM_TYPE_AMD64) \
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync && ( PGM_GST_TYPE == PGM_TYPE_REAL \
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync || PGM_GST_TYPE == PGM_TYPE_PROT))
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync Assert(!HWACCMIsNestedPagingActive(pVM));
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync /* We only need shadow paging in real and protected mode for VT-x and AMD-V (excluding nested paging/EPT modes) */
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync if (HWACCMR3IsActive(pVM))
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync {
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync /* Free the previous root mapping if still active. */
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync if (pVM->pgm.s.CTX_SUFF(pShwPageCR3))
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync {
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync /* It might have been freed already by a pool flush (see e.g. PGMR3MappingsUnfix). */
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync /** @todo Coordinate this better with the pool. */
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync if (pVM->pgm.s.CTX_SUFF(pShwPageCR3)->enmKind != PGMPOOLKIND_FREE)
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync pgmPoolFreeByPage(pPool, pVM->pgm.s.CTX_SUFF(pShwPageCR3), pVM->pgm.s.CTX_SUFF(pShwPageCR3)->iUser, pVM->pgm.s.CTX_SUFF(pShwPageCR3)->iUserTable);
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync pVM->pgm.s.pShwPageCR3R3 = 0;
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync pVM->pgm.s.pShwPageCR3R0 = 0;
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync pVM->pgm.s.pShwRootR3 = 0;
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync# ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync pVM->pgm.s.pShwRootR0 = 0;
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync# endif
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync pVM->pgm.s.HCPhysShwCR3 = 0;
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync pVM->pgm.s.iShwUser = 0;
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync pVM->pgm.s.iShwUserTable = 0;
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync }
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync /* contruct a fake address */
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync# if PGM_GST_TYPE == PGM_TYPE_REAL
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync RTGCPHYS GCPhysCR3 = RT_BIT_64(63);
726fc44ad0bd65a178ad4c3ab46ebd6cd3208e99vboxsync# else
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync RTGCPHYS GCPhysCR3 = RT_BIT_64(63) | RT_BIT_64(62);
26824086a3f6b36cd911058f1d9b4c0b944706fbvboxsync# endif
26824086a3f6b36cd911058f1d9b4c0b944706fbvboxsync pVM->pgm.s.iShwUser = SHW_POOL_ROOT_IDX;
26824086a3f6b36cd911058f1d9b4c0b944706fbvboxsync pVM->pgm.s.iShwUserTable = GCPhysCR3 >> PAGE_SHIFT;
68ef804c4ec232c58e2c03c8fc6afe3765c5c0d1vboxsync int rc = pgmPoolAlloc(pVM, GCPhysCR3, BTH_PGMPOOLKIND_ROOT, pVM->pgm.s.iShwUser, pVM->pgm.s.iShwUserTable, &pVM->pgm.s.CTX_SUFF(pShwPageCR3));
68ef804c4ec232c58e2c03c8fc6afe3765c5c0d1vboxsync if (rc == VERR_PGM_POOL_FLUSHED)
68ef804c4ec232c58e2c03c8fc6afe3765c5c0d1vboxsync {
3080f6c0871099df43a4e91b31894d9c2b1369a8vboxsync Log(("Bth-Enter: PGM pool flushed -> signal sync cr3\n"));
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync Assert(VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync return VINF_PGM_SYNC_CR3;
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync }
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync AssertRCReturn(rc, rc);
26824086a3f6b36cd911058f1d9b4c0b944706fbvboxsync# ifdef IN_RING0
26824086a3f6b36cd911058f1d9b4c0b944706fbvboxsync pVM->pgm.s.pShwPageCR3R3 = MMHyperCCToR3(pVM, pVM->pgm.s.CTX_SUFF(pShwPageCR3));
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync# else
b8aaccdbdd143967110d499670605dd7ff6ecc72vboxsync pVM->pgm.s.pShwPageCR3R0 = MMHyperCCToR0(pVM, pVM->pgm.s.CTX_SUFF(pShwPageCR3));
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync# endif
50df3da42ff6589b0ecc4f50f2288811bc370186vboxsync pVM->pgm.s.pShwRootR3 = (R3PTRTYPE(void *))pVM->pgm.s.CTX_SUFF(pShwPageCR3)->pvPageR3;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Assert(pVM->pgm.s.pShwRootR3);
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync# ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pVM->pgm.s.pShwRootR0 = (R0PTRTYPE(void *))PGMPOOL_PAGE_2_PTR(pPool->CTX_SUFF(pVM), pVM->pgm.s.CTX_SUFF(pShwPageCR3));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pVM->pgm.s.HCPhysShwCR3 = pVM->pgm.s.CTX_SUFF(pShwPageCR3)->Core.Key;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync# endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* nothing special to do here - InitData does the job. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Relocate any GC pointers related to shadow mode paging.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @returns VBox status code.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param pVM The VM handle.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param offDelta The reloation offset.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPGM_BTH_DECL(int, Relocate)(PVM pVM, RTGCPTR offDelta)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* nothing special to do here - InitData does the job. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return VINF_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync