PGMShw.h revision d099ccfb66d26601f93e7967e8e73cee4b9c62df
54a2dc8050116a473e8644b8d096dd99fcee1ec5vboxsync/* $Id$ */
54a2dc8050116a473e8644b8d096dd99fcee1ec5vboxsync/** @file
54a2dc8050116a473e8644b8d096dd99fcee1ec5vboxsync * VBox - Page Manager / Monitor, Shadow Paging Template.
54a2dc8050116a473e8644b8d096dd99fcee1ec5vboxsync */
54a2dc8050116a473e8644b8d096dd99fcee1ec5vboxsync
54a2dc8050116a473e8644b8d096dd99fcee1ec5vboxsync/*
c76aa9ecac0d701ddd7939c9be92469ea1d1bd95vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
c76aa9ecac0d701ddd7939c9be92469ea1d1bd95vboxsync *
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 *
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
183bc517a9dca5a54ba6701581066363e78de360vboxsync/*******************************************************************************
183bc517a9dca5a54ba6701581066363e78de360vboxsync* Defined Constants And Macros *
183bc517a9dca5a54ba6701581066363e78de360vboxsync*******************************************************************************/
07bf6fe4d148098a220a6b278d2248941b717acdvboxsync#undef SHWPT
07bf6fe4d148098a220a6b278d2248941b717acdvboxsync#undef PSHWPT
07bf6fe4d148098a220a6b278d2248941b717acdvboxsync#undef SHWPTE
07bf6fe4d148098a220a6b278d2248941b717acdvboxsync#undef PSHWPTE
07bf6fe4d148098a220a6b278d2248941b717acdvboxsync#undef SHWPD
07bf6fe4d148098a220a6b278d2248941b717acdvboxsync#undef PSHWPD
012cc5b1a05944f69bcc8a95e13da7cd7f0379e5vboxsync#undef SHWPDE
012cc5b1a05944f69bcc8a95e13da7cd7f0379e5vboxsync#undef PSHWPDE
012cc5b1a05944f69bcc8a95e13da7cd7f0379e5vboxsync#undef SHW_PDE_PG_MASK
012cc5b1a05944f69bcc8a95e13da7cd7f0379e5vboxsync#undef SHW_PD_SHIFT
012cc5b1a05944f69bcc8a95e13da7cd7f0379e5vboxsync#undef SHW_PD_MASK
012cc5b1a05944f69bcc8a95e13da7cd7f0379e5vboxsync#undef SHW_PTE_PG_MASK
7971d68750815895622e31b4c1a86913dd58810evboxsync#undef SHW_PT_SHIFT
7971d68750815895622e31b4c1a86913dd58810evboxsync#undef SHW_PT_MASK
7971d68750815895622e31b4c1a86913dd58810evboxsync#undef SHW_TOTAL_PD_ENTRIES
7971d68750815895622e31b4c1a86913dd58810evboxsync#undef SHW_PDPT_SHIFT
7971d68750815895622e31b4c1a86913dd58810evboxsync#undef SHW_PDPT_MASK
7971d68750815895622e31b4c1a86913dd58810evboxsync#undef SHW_PDPE_PG_MASK
79dc091db288c096b6e03888a095477ded84f503vboxsync#undef SHW_POOL_ROOT_IDX
8af51386c2aa6a8411193dc96c79cbef7dd8f2d1vboxsync
8af51386c2aa6a8411193dc96c79cbef7dd8f2d1vboxsync#if PGM_SHW_TYPE == PGM_TYPE_32BIT
8af51386c2aa6a8411193dc96c79cbef7dd8f2d1vboxsync# define SHWPT X86PT
79dc091db288c096b6e03888a095477ded84f503vboxsync# define PSHWPT PX86PT
8af51386c2aa6a8411193dc96c79cbef7dd8f2d1vboxsync# define SHWPTE X86PTE
2675fd1e482998dd3a2e947b1aa7484317dd094evboxsync# define PSHWPTE PX86PTE
2675fd1e482998dd3a2e947b1aa7484317dd094evboxsync# define SHWPD X86PD
2675fd1e482998dd3a2e947b1aa7484317dd094evboxsync# define PSHWPD PX86PD
2675fd1e482998dd3a2e947b1aa7484317dd094evboxsync# define SHWPDE X86PDE
2675fd1e482998dd3a2e947b1aa7484317dd094evboxsync# define PSHWPDE PX86PDE
2675fd1e482998dd3a2e947b1aa7484317dd094evboxsync# define SHW_PDE_PG_MASK X86_PDE_PG_MASK
ce00b469e756b0f651b7aa020c9440e991d3442dvboxsync# define SHW_PD_SHIFT X86_PD_SHIFT
ce00b469e756b0f651b7aa020c9440e991d3442dvboxsync# define SHW_PD_MASK X86_PD_MASK
ce00b469e756b0f651b7aa020c9440e991d3442dvboxsync# define SHW_TOTAL_PD_ENTRIES X86_PG_ENTRIES
ce00b469e756b0f651b7aa020c9440e991d3442dvboxsync# define SHW_PTE_PG_MASK X86_PTE_PG_MASK
ce00b469e756b0f651b7aa020c9440e991d3442dvboxsync# define SHW_PT_SHIFT X86_PT_SHIFT
ce00b469e756b0f651b7aa020c9440e991d3442dvboxsync# define SHW_PT_MASK X86_PT_MASK
2909d70e58e87e2111fdc5265d1ab32a08d557a3vboxsync# define SHW_POOL_ROOT_IDX PGMPOOL_IDX_PD
2909d70e58e87e2111fdc5265d1ab32a08d557a3vboxsync
2909d70e58e87e2111fdc5265d1ab32a08d557a3vboxsync#elif PGM_SHW_TYPE == PGM_TYPE_EPT
2909d70e58e87e2111fdc5265d1ab32a08d557a3vboxsync# define SHWPT EPTPT
2909d70e58e87e2111fdc5265d1ab32a08d557a3vboxsync# define PSHWPT PEPTPT
2909d70e58e87e2111fdc5265d1ab32a08d557a3vboxsync# define SHWPTE EPTPTE
9875b4d1f31a47c8c0f71430b7c9e0113104d064vboxsync# define PSHWPTE PEPTPTE
9875b4d1f31a47c8c0f71430b7c9e0113104d064vboxsync# define SHWPD EPTPD
9875b4d1f31a47c8c0f71430b7c9e0113104d064vboxsync# define PSHWPD PEPTPD
9875b4d1f31a47c8c0f71430b7c9e0113104d064vboxsync# define SHWPDE EPTPDE
9875b4d1f31a47c8c0f71430b7c9e0113104d064vboxsync# define PSHWPDE PEPTPDE
9875b4d1f31a47c8c0f71430b7c9e0113104d064vboxsync# define SHW_PDE_PG_MASK EPT_PDE_PG_MASK
3d8242e90019d302159795040e410b3d774a4b0bvboxsync# define SHW_PD_SHIFT EPT_PD_SHIFT
3d8242e90019d302159795040e410b3d774a4b0bvboxsync# define SHW_PD_MASK EPT_PD_MASK
3d8242e90019d302159795040e410b3d774a4b0bvboxsync# define SHW_PTE_PG_MASK EPT_PTE_PG_MASK
3d8242e90019d302159795040e410b3d774a4b0bvboxsync# define SHW_PT_SHIFT EPT_PT_SHIFT
3d8242e90019d302159795040e410b3d774a4b0bvboxsync# define SHW_PT_MASK EPT_PT_MASK
3d8242e90019d302159795040e410b3d774a4b0bvboxsync# define SHW_PDPT_SHIFT EPT_PDPT_SHIFT
534226d9c71bac7817fbcfeace5cf548084d7f6cvboxsync# define SHW_PDPT_MASK EPT_PDPT_MASK
534226d9c71bac7817fbcfeace5cf548084d7f6cvboxsync# define SHW_PDPE_PG_MASK EPT_PDPE_PG_MASK
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. */
3d8242e90019d302159795040e410b3d774a4b0bvboxsync
534226d9c71bac7817fbcfeace5cf548084d7f6cvboxsync#else
b10aac1b449f12e70468efd9eb414ba4d2a0c029vboxsync# define SHWPT X86PTPAE
b10aac1b449f12e70468efd9eb414ba4d2a0c029vboxsync# define PSHWPT PX86PTPAE
b10aac1b449f12e70468efd9eb414ba4d2a0c029vboxsync# define SHWPTE X86PTEPAE
b10aac1b449f12e70468efd9eb414ba4d2a0c029vboxsync# define PSHWPTE PX86PTEPAE
3d8242e90019d302159795040e410b3d774a4b0bvboxsync# define SHWPD X86PDPAE
b10aac1b449f12e70468efd9eb414ba4d2a0c029vboxsync# define PSHWPD PX86PDPAE
5896bf5b1db43d4c2d0974e137cb1d2ad174643fvboxsync# define SHWPDE X86PDEPAE
5896bf5b1db43d4c2d0974e137cb1d2ad174643fvboxsync# define PSHWPDE PX86PDEPAE
5896bf5b1db43d4c2d0974e137cb1d2ad174643fvboxsync# define SHW_PDE_PG_MASK X86_PDE_PAE_PG_MASK
5896bf5b1db43d4c2d0974e137cb1d2ad174643fvboxsync# define SHW_PD_SHIFT X86_PD_PAE_SHIFT
5896bf5b1db43d4c2d0974e137cb1d2ad174643fvboxsync# define SHW_PD_MASK X86_PD_PAE_MASK
5896bf5b1db43d4c2d0974e137cb1d2ad174643fvboxsync# define SHW_PTE_PG_MASK X86_PTE_PAE_PG_MASK
8cde32eca33c0b47371ed3ba58e4d2cceed0b548vboxsync# define SHW_PT_SHIFT X86_PT_PAE_SHIFT
8cde32eca33c0b47371ed3ba58e4d2cceed0b548vboxsync# define SHW_PT_MASK X86_PT_PAE_MASK
8cde32eca33c0b47371ed3ba58e4d2cceed0b548vboxsync
8cde32eca33c0b47371ed3ba58e4d2cceed0b548vboxsync# if PGM_SHW_TYPE == PGM_TYPE_AMD64
8cde32eca33c0b47371ed3ba58e4d2cceed0b548vboxsync# define SHW_PDPT_SHIFT X86_PDPT_SHIFT
8cde32eca33c0b47371ed3ba58e4d2cceed0b548vboxsync# define SHW_PDPT_MASK X86_PDPT_MASK_AMD64
f5840fca26963de38533fd43c951758c386ed60avboxsync# define SHW_PDPE_PG_MASK X86_PDPE_PG_MASK
f5840fca26963de38533fd43c951758c386ed60avboxsync# define SHW_TOTAL_PD_ENTRIES (X86_PG_AMD64_ENTRIES*X86_PG_AMD64_PDPE_ENTRIES)
f5840fca26963de38533fd43c951758c386ed60avboxsync# define SHW_POOL_ROOT_IDX PGMPOOL_IDX_AMD64_CR3
f5840fca26963de38533fd43c951758c386ed60avboxsync
f5840fca26963de38533fd43c951758c386ed60avboxsync# else /* 32 bits PAE mode */
f5840fca26963de38533fd43c951758c386ed60avboxsync# define SHW_PDPT_SHIFT X86_PDPT_SHIFT
1400154bf298b7208c611e81321e0c82b721afd7vboxsync# define SHW_PDPT_MASK X86_PDPT_MASK_PAE
1400154bf298b7208c611e81321e0c82b721afd7vboxsync# define SHW_PDPE_PG_MASK X86_PDPE_PG_MASK
1400154bf298b7208c611e81321e0c82b721afd7vboxsync# define SHW_TOTAL_PD_ENTRIES (X86_PG_PAE_ENTRIES*X86_PG_PAE_PDPE_ENTRIES)
1400154bf298b7208c611e81321e0c82b721afd7vboxsync# define SHW_POOL_ROOT_IDX PGMPOOL_IDX_PDPT
1400154bf298b7208c611e81321e0c82b721afd7vboxsync# endif
1400154bf298b7208c611e81321e0c82b721afd7vboxsync#endif
af66a95ff0d75da2d50719eb14a686a9de7bff76vboxsync
af66a95ff0d75da2d50719eb14a686a9de7bff76vboxsync
af66a95ff0d75da2d50719eb14a686a9de7bff76vboxsync/*******************************************************************************
af66a95ff0d75da2d50719eb14a686a9de7bff76vboxsync* Internal Functions *
af66a95ff0d75da2d50719eb14a686a9de7bff76vboxsync*******************************************************************************/
af66a95ff0d75da2d50719eb14a686a9de7bff76vboxsyncRT_C_DECLS_BEGIN
8d56e4d4be56ac2cbe2c03ce678432c6d8d1d7d3vboxsync/* r3 */
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);
8d56e4d4be56ac2cbe2c03ce678432c6d8d1d7d3vboxsyncPGM_SHW_DECL(int, Exit)(PVMCPU pVCpu);
8d56e4d4be56ac2cbe2c03ce678432c6d8d1d7d3vboxsync
5a1e64cee1eec57da3361ccda90351bd9c2e97a6vboxsync/* all */
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);
5a1e64cee1eec57da3361ccda90351bd9c2e97a6vboxsyncRT_C_DECLS_END
5a1e64cee1eec57da3361ccda90351bd9c2e97a6vboxsync
5a1e64cee1eec57da3361ccda90351bd9c2e97a6vboxsync
fdb7d72fbf00de23e58088243b932f48684e83davboxsync/**
fdb7d72fbf00de23e58088243b932f48684e83davboxsync * Initializes the guest bit of the paging mode data.
fdb7d72fbf00de23e58088243b932f48684e83davboxsync *
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.
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync */
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsyncPGM_SHW_DECL(int, InitData)(PVM pVM, PPGMMODEDATA pModeData, bool fResolveGCAndR0)
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync{
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync Assert(pModeData->uShwType == PGM_SHW_TYPE || pModeData->uShwType == PGM_TYPE_NESTED);
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync /* Ring-3 */
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync pModeData->pfnR3ShwRelocate = PGM_SHW_NAME(Relocate);
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync pModeData->pfnR3ShwExit = PGM_SHW_NAME(Exit);
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync pModeData->pfnR3ShwGetPage = PGM_SHW_NAME(GetPage);
0a45dc6fc6692b57703e7e251f63b36476cc3435vboxsync pModeData->pfnR3ShwModifyPage = PGM_SHW_NAME(ModifyPage);
e5ece1e2eda83c3ac47fc02dc4d343e430009381vboxsync
e5ece1e2eda83c3ac47fc02dc4d343e430009381vboxsync if (fResolveGCAndR0)
e5ece1e2eda83c3ac47fc02dc4d343e430009381vboxsync {
e5ece1e2eda83c3ac47fc02dc4d343e430009381vboxsync int rc;
4148135d7797d294ed20b17713f3792aedb4426dvboxsync
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 /* GC */
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. */
05b0c045e695a3e2dfe0e3f3ad0909f061f28272vboxsync
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 }
fae3aa27fee8a48462bbdb535cc8674f66249f6bvboxsync return VINF_SUCCESS;
fae3aa27fee8a48462bbdb535cc8674f66249f6bvboxsync}
fae3aa27fee8a48462bbdb535cc8674f66249f6bvboxsync
fae3aa27fee8a48462bbdb535cc8674f66249f6bvboxsync/**
fae3aa27fee8a48462bbdb535cc8674f66249f6bvboxsync * Enters the shadow mode.
02ab40eecbb0eb6b6cf6101439e1b2c40ff169d2vboxsync *
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)
02ab40eecbb0eb6b6cf6101439e1b2c40ff169d2vboxsync */
02ab40eecbb0eb6b6cf6101439e1b2c40ff169d2vboxsyncPGM_SHW_DECL(int, Enter)(PVMCPU pVCpu, bool fIs64BitsPagingMode)
a4b0396828d3dfafb72e49a456c926b62bd19fb4vboxsync{
a4b0396828d3dfafb72e49a456c926b62bd19fb4vboxsync#if PGM_SHW_TYPE == PGM_TYPE_NESTED || PGM_SHW_TYPE == PGM_TYPE_EPT
a4b0396828d3dfafb72e49a456c926b62bd19fb4vboxsync
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);
ecb894e73b05a2c316a46cda31b899d54a6ae9d3vboxsync# else
ecb894e73b05a2c316a46cda31b899d54a6ae9d3vboxsync RTGCPHYS GCPhysCR3 = RT_BIT_64(63);
ecb894e73b05a2c316a46cda31b899d54a6ae9d3vboxsync# endif
ecb894e73b05a2c316a46cda31b899d54a6ae9d3vboxsync PPGMPOOLPAGE pNewShwPageCR3;
ecb894e73b05a2c316a46cda31b899d54a6ae9d3vboxsync PVM pVM = pVCpu->pVMR3;
ecb894e73b05a2c316a46cda31b899d54a6ae9d3vboxsync PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync Assert(HWACCMIsNestedPagingActive(pVM));
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync Assert(!pVCpu->pgm.s.pShwPageCR3R3);
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync pgmLock(pVM);
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync int rc = pgmPoolAlloc(pVM, GCPhysCR3, PGMPOOLKIND_ROOT_NESTED, PGMPOOL_IDX_NESTED_ROOT, GCPhysCR3 >> PAGE_SHIFT, &pNewShwPageCR3, true /* lock page */);
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync AssertFatalRC(rc);
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync pVCpu->pgm.s.iShwUser = PGMPOOL_IDX_NESTED_ROOT;
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync pVCpu->pgm.s.iShwUserTable = GCPhysCR3 >> PAGE_SHIFT;
90a35323c5f9ed1401511bf7e94b65575ac09ecbvboxsync pVCpu->pgm.s.pShwPageCR3R3 = pNewShwPageCR3;
1c65c68707cffcad0ea498eba4da76fa07bf2d6cvboxsync
1c65c68707cffcad0ea498eba4da76fa07bf2d6cvboxsync pVCpu->pgm.s.pShwPageCR3RC = MMHyperCCToRC(pVM, pVCpu->pgm.s.pShwPageCR3R3);
1c65c68707cffcad0ea498eba4da76fa07bf2d6cvboxsync pVCpu->pgm.s.pShwPageCR3R0 = MMHyperCCToR0(pVM, pVCpu->pgm.s.pShwPageCR3R3);
1c65c68707cffcad0ea498eba4da76fa07bf2d6cvboxsync
1c65c68707cffcad0ea498eba4da76fa07bf2d6cvboxsync pgmUnlock(pVM);
1c65c68707cffcad0ea498eba4da76fa07bf2d6cvboxsync
b511f3c653d106f51f22f5015f6a24cc6e1108d6vboxsync Log(("Enter nested shadow paging mode: root %RHv phys %RHp\n", pVCpu->pgm.s.pShwPageCR3R3, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3)->Core.Key));
b511f3c653d106f51f22f5015f6a24cc6e1108d6vboxsync#endif
b511f3c653d106f51f22f5015f6a24cc6e1108d6vboxsync return VINF_SUCCESS;
b511f3c653d106f51f22f5015f6a24cc6e1108d6vboxsync}
b511f3c653d106f51f22f5015f6a24cc6e1108d6vboxsync
b511f3c653d106f51f22f5015f6a24cc6e1108d6vboxsync
73130ef6d5209630eb0e7baa07415cad1a7791dbvboxsync/**
73130ef6d5209630eb0e7baa07415cad1a7791dbvboxsync * Relocate any GC pointers related to shadow mode paging.
73130ef6d5209630eb0e7baa07415cad1a7791dbvboxsync *
73130ef6d5209630eb0e7baa07415cad1a7791dbvboxsync * @returns VBox status code.
b511f3c653d106f51f22f5015f6a24cc6e1108d6vboxsync * @param pVCpu The VMCPU to operate on.
73130ef6d5209630eb0e7baa07415cad1a7791dbvboxsync * @param offDelta The reloation offset.
aa42629e12e555ed393a4e1a0580560de23f01f9vboxsync */
aa42629e12e555ed393a4e1a0580560de23f01f9vboxsyncPGM_SHW_DECL(int, Relocate)(PVMCPU pVCpu, RTGCPTR offDelta)
aa42629e12e555ed393a4e1a0580560de23f01f9vboxsync{
aa42629e12e555ed393a4e1a0580560de23f01f9vboxsync pVCpu->pgm.s.pShwPageCR3RC += offDelta;
aa42629e12e555ed393a4e1a0580560de23f01f9vboxsync return VINF_SUCCESS;
aa42629e12e555ed393a4e1a0580560de23f01f9vboxsync}
8f15b6c92cae9a259476b2e462522fe42851682bvboxsync
8f15b6c92cae9a259476b2e462522fe42851682bvboxsync
8f15b6c92cae9a259476b2e462522fe42851682bvboxsync/**
8f15b6c92cae9a259476b2e462522fe42851682bvboxsync * Exits the shadow mode.
8f15b6c92cae9a259476b2e462522fe42851682bvboxsync *
8f15b6c92cae9a259476b2e462522fe42851682bvboxsync * @returns VBox status code.
3533947350580467c10357b0632723f8894c2470vboxsync * @param pVCpu The VMCPU to operate on.
3533947350580467c10357b0632723f8894c2470vboxsync */
3533947350580467c10357b0632723f8894c2470vboxsyncPGM_SHW_DECL(int, Exit)(PVMCPU pVCpu)
3533947350580467c10357b0632723f8894c2470vboxsync{
3533947350580467c10357b0632723f8894c2470vboxsync PVM pVM = pVCpu->pVMR3;
3533947350580467c10357b0632723f8894c2470vboxsync
2f039d2bda433dc9a6dc5aaa391bd7e1d3341989vboxsync if ( ( pVCpu->pgm.s.enmShadowMode == PGMMODE_NESTED
2f039d2bda433dc9a6dc5aaa391bd7e1d3341989vboxsync || pVCpu->pgm.s.enmShadowMode == PGMMODE_EPT)
2f039d2bda433dc9a6dc5aaa391bd7e1d3341989vboxsync && pVCpu->pgm.s.CTX_SUFF(pShwPageCR3))
2f039d2bda433dc9a6dc5aaa391bd7e1d3341989vboxsync {
3533947350580467c10357b0632723f8894c2470vboxsync PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
2f039d2bda433dc9a6dc5aaa391bd7e1d3341989vboxsync
3bca454544ce3065366c6bf3cc297e3b4712cbc5vboxsync Assert(pVCpu->pgm.s.iShwUser == PGMPOOL_IDX_NESTED_ROOT);
3bca454544ce3065366c6bf3cc297e3b4712cbc5vboxsync
3bca454544ce3065366c6bf3cc297e3b4712cbc5vboxsync pgmLock(pVM);
3bca454544ce3065366c6bf3cc297e3b4712cbc5vboxsync
3bca454544ce3065366c6bf3cc297e3b4712cbc5vboxsync /* Mark the page as unlocked; allow flushing again. */
3bca454544ce3065366c6bf3cc297e3b4712cbc5vboxsync pgmPoolUnlockPage(pPool, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3));
be1dd15477123f3633a92feb71cc85c226792be8vboxsync
be1dd15477123f3633a92feb71cc85c226792be8vboxsync pgmPoolFreeByPage(pPool, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3), pVCpu->pgm.s.iShwUser, pVCpu->pgm.s.iShwUserTable);
be1dd15477123f3633a92feb71cc85c226792be8vboxsync pVCpu->pgm.s.pShwPageCR3R3 = 0;
be1dd15477123f3633a92feb71cc85c226792be8vboxsync pVCpu->pgm.s.pShwPageCR3R0 = 0;
be1dd15477123f3633a92feb71cc85c226792be8vboxsync pVCpu->pgm.s.pShwPageCR3RC = 0;
be1dd15477123f3633a92feb71cc85c226792be8vboxsync pVCpu->pgm.s.iShwUser = 0;
9d5272fbe8e54529a74cbcf80d80b1741b23b5bavboxsync pVCpu->pgm.s.iShwUserTable = 0;
9d5272fbe8e54529a74cbcf80d80b1741b23b5bavboxsync
9d5272fbe8e54529a74cbcf80d80b1741b23b5bavboxsync pgmUnlock(pVM);
9d5272fbe8e54529a74cbcf80d80b1741b23b5bavboxsync
9d5272fbe8e54529a74cbcf80d80b1741b23b5bavboxsync Log(("Leave nested shadow paging mode\n"));
9d5272fbe8e54529a74cbcf80d80b1741b23b5bavboxsync }
acc3fa2429f21581119fc32b32f1b3ad51118eacvboxsync return VINF_SUCCESS;
acc3fa2429f21581119fc32b32f1b3ad51118eacvboxsync}
acc3fa2429f21581119fc32b32f1b3ad51118eacvboxsync
acc3fa2429f21581119fc32b32f1b3ad51118eacvboxsync