VirtualBox

Changeset 79202 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jun 18, 2019 9:13:29 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
131377
Message:

VMM: Nested VMX: bugref:9180 VMCS shadowing, work in progress.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r79194 r79202  
    36073607     * encoding (i.e. bit 12).
    36083608     */
    3609     if (u64FieldEnc & VMX_VMCS_ENC_RSVD_MASK)
     3609    if (u64FieldEnc & VMX_VMCSFIELD_RSVD_MASK)
    36103610        return true;
    36113611
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r79167 r79202  
    2525#include <iprt/asm-amd64-x86.h>
    2626#include <iprt/thread.h>
     27#include <iprt/mem.h>
    2728
    2829#include <VBox/vmm/pdmapi.h>
     
    489490*   Global Variables                                                                                                             *
    490491*********************************************************************************************************************************/
     492#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     493/**
     494 * Array of all VMCS fields.
     495 * Any fields added to the VT-x spec. should be added here.
     496 *
     497 * Currently only used to derive shadow VMCS fields for hardware-assisted execution
     498 * of nested-guests.
     499 */
     500static const uint32_t g_aVmcsFields[] =
     501{
     502    /* 16-bit control fields. */
     503    VMX_VMCS16_VPID,
     504    VMX_VMCS16_POSTED_INT_NOTIFY_VECTOR,
     505    VMX_VMCS16_EPTP_INDEX,
     506
     507    /* 16-bit guest-state fields. */
     508    VMX_VMCS16_GUEST_ES_SEL,
     509    VMX_VMCS16_GUEST_CS_SEL,
     510    VMX_VMCS16_GUEST_SS_SEL,
     511    VMX_VMCS16_GUEST_DS_SEL,
     512    VMX_VMCS16_GUEST_FS_SEL,
     513    VMX_VMCS16_GUEST_GS_SEL,
     514    VMX_VMCS16_GUEST_LDTR_SEL,
     515    VMX_VMCS16_GUEST_TR_SEL,
     516    VMX_VMCS16_GUEST_INTR_STATUS,
     517    VMX_VMCS16_GUEST_PML_INDEX,
     518
     519    /* 16-bits host-state fields. */
     520    VMX_VMCS16_HOST_ES_SEL,
     521    VMX_VMCS16_HOST_CS_SEL,
     522    VMX_VMCS16_HOST_SS_SEL,
     523    VMX_VMCS16_HOST_DS_SEL,
     524    VMX_VMCS16_HOST_FS_SEL,
     525    VMX_VMCS16_HOST_GS_SEL,
     526    VMX_VMCS16_HOST_TR_SEL,
     527
     528    /* 64-bit control fields. */
     529    VMX_VMCS64_CTRL_IO_BITMAP_A_FULL,
     530    VMX_VMCS64_CTRL_IO_BITMAP_A_HIGH,
     531    VMX_VMCS64_CTRL_IO_BITMAP_B_FULL,
     532    VMX_VMCS64_CTRL_IO_BITMAP_B_HIGH,
     533    VMX_VMCS64_CTRL_MSR_BITMAP_FULL,
     534    VMX_VMCS64_CTRL_MSR_BITMAP_HIGH,
     535    VMX_VMCS64_CTRL_EXIT_MSR_STORE_FULL,
     536    VMX_VMCS64_CTRL_EXIT_MSR_STORE_HIGH,
     537    VMX_VMCS64_CTRL_EXIT_MSR_LOAD_FULL,
     538    VMX_VMCS64_CTRL_EXIT_MSR_LOAD_HIGH,
     539    VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_FULL,
     540    VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_HIGH,
     541    VMX_VMCS64_CTRL_EXEC_VMCS_PTR_FULL,
     542    VMX_VMCS64_CTRL_EXEC_VMCS_PTR_HIGH,
     543    VMX_VMCS64_CTRL_EXEC_PML_ADDR_FULL,
     544    VMX_VMCS64_CTRL_EXEC_PML_ADDR_HIGH,
     545    VMX_VMCS64_CTRL_TSC_OFFSET_FULL,
     546    VMX_VMCS64_CTRL_TSC_OFFSET_HIGH,
     547    VMX_VMCS64_CTRL_VIRT_APIC_PAGEADDR_FULL,
     548    VMX_VMCS64_CTRL_VIRT_APIC_PAGEADDR_HIGH,
     549    VMX_VMCS64_CTRL_APIC_ACCESSADDR_FULL,
     550    VMX_VMCS64_CTRL_APIC_ACCESSADDR_HIGH,
     551    VMX_VMCS64_CTRL_POSTED_INTR_DESC_FULL,
     552    VMX_VMCS64_CTRL_POSTED_INTR_DESC_HIGH,
     553    VMX_VMCS64_CTRL_VMFUNC_CTRLS_FULL,
     554    VMX_VMCS64_CTRL_VMFUNC_CTRLS_HIGH,
     555    VMX_VMCS64_CTRL_EPTP_FULL,
     556    VMX_VMCS64_CTRL_EPTP_HIGH,
     557    VMX_VMCS64_CTRL_EOI_BITMAP_0_FULL,
     558    VMX_VMCS64_CTRL_EOI_BITMAP_0_HIGH,
     559    VMX_VMCS64_CTRL_EOI_BITMAP_1_FULL,
     560    VMX_VMCS64_CTRL_EOI_BITMAP_1_HIGH,
     561    VMX_VMCS64_CTRL_EOI_BITMAP_2_FULL,
     562    VMX_VMCS64_CTRL_EOI_BITMAP_2_HIGH,
     563    VMX_VMCS64_CTRL_EOI_BITMAP_3_FULL,
     564    VMX_VMCS64_CTRL_EOI_BITMAP_3_HIGH,
     565    VMX_VMCS64_CTRL_EPTP_LIST_FULL,
     566    VMX_VMCS64_CTRL_EPTP_LIST_HIGH,
     567    VMX_VMCS64_CTRL_VMREAD_BITMAP_FULL,
     568    VMX_VMCS64_CTRL_VMREAD_BITMAP_HIGH,
     569    VMX_VMCS64_CTRL_VMWRITE_BITMAP_FULL,
     570    VMX_VMCS64_CTRL_VMWRITE_BITMAP_HIGH,
     571    VMX_VMCS64_CTRL_VIRTXCPT_INFO_ADDR_FULL,
     572    VMX_VMCS64_CTRL_VIRTXCPT_INFO_ADDR_HIGH,
     573    VMX_VMCS64_CTRL_XSS_EXITING_BITMAP_FULL,
     574    VMX_VMCS64_CTRL_XSS_EXITING_BITMAP_HIGH,
     575    VMX_VMCS64_CTRL_ENCLS_EXITING_BITMAP_FULL,
     576    VMX_VMCS64_CTRL_ENCLS_EXITING_BITMAP_HIGH,
     577    VMX_VMCS64_CTRL_TSC_MULTIPLIER_FULL,
     578    VMX_VMCS64_CTRL_TSC_MULTIPLIER_HIGH,
     579
     580    /* 64-bit read-only data fields. */
     581    VMX_VMCS64_RO_GUEST_PHYS_ADDR_FULL,
     582    VMX_VMCS64_RO_GUEST_PHYS_ADDR_HIGH,
     583
     584    /* 64-bit guest-state fields. */
     585    VMX_VMCS64_GUEST_VMCS_LINK_PTR_FULL,
     586    VMX_VMCS64_GUEST_VMCS_LINK_PTR_HIGH,
     587    VMX_VMCS64_GUEST_DEBUGCTL_FULL,
     588    VMX_VMCS64_GUEST_DEBUGCTL_HIGH,
     589    VMX_VMCS64_GUEST_PAT_FULL,
     590    VMX_VMCS64_GUEST_PAT_HIGH,
     591    VMX_VMCS64_GUEST_EFER_FULL,
     592    VMX_VMCS64_GUEST_EFER_HIGH,
     593    VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_FULL,
     594    VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_HIGH,
     595    VMX_VMCS64_GUEST_PDPTE0_FULL,
     596    VMX_VMCS64_GUEST_PDPTE0_HIGH,
     597    VMX_VMCS64_GUEST_PDPTE1_FULL,
     598    VMX_VMCS64_GUEST_PDPTE1_HIGH,
     599    VMX_VMCS64_GUEST_PDPTE2_FULL,
     600    VMX_VMCS64_GUEST_PDPTE2_HIGH,
     601    VMX_VMCS64_GUEST_PDPTE3_FULL,
     602    VMX_VMCS64_GUEST_PDPTE3_HIGH,
     603    VMX_VMCS64_GUEST_BNDCFGS_FULL,
     604    VMX_VMCS64_GUEST_BNDCFGS_HIGH,
     605
     606    /* 64-bit host-state fields. */
     607    VMX_VMCS64_HOST_PAT_FULL,
     608    VMX_VMCS64_HOST_PAT_HIGH,
     609    VMX_VMCS64_HOST_EFER_FULL,
     610    VMX_VMCS64_HOST_EFER_HIGH,
     611    VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_FULL,
     612    VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_HIGH,
     613
     614    /* 32-bit control fields. */
     615    VMX_VMCS32_CTRL_PIN_EXEC,
     616    VMX_VMCS32_CTRL_PROC_EXEC,
     617    VMX_VMCS32_CTRL_EXCEPTION_BITMAP,
     618    VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MASK,
     619    VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MATCH,
     620    VMX_VMCS32_CTRL_CR3_TARGET_COUNT,
     621    VMX_VMCS32_CTRL_EXIT,
     622    VMX_VMCS32_CTRL_EXIT_MSR_STORE_COUNT,
     623    VMX_VMCS32_CTRL_EXIT_MSR_LOAD_COUNT,
     624    VMX_VMCS32_CTRL_ENTRY,
     625    VMX_VMCS32_CTRL_ENTRY_MSR_LOAD_COUNT,
     626    VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO,
     627    VMX_VMCS32_CTRL_ENTRY_EXCEPTION_ERRCODE,
     628    VMX_VMCS32_CTRL_ENTRY_INSTR_LENGTH,
     629    VMX_VMCS32_CTRL_TPR_THRESHOLD,
     630    VMX_VMCS32_CTRL_PROC_EXEC2,
     631    VMX_VMCS32_CTRL_PLE_GAP,
     632    VMX_VMCS32_CTRL_PLE_WINDOW,
     633
     634    /* 32-bits read-only fields. */
     635    VMX_VMCS32_RO_VM_INSTR_ERROR,
     636    VMX_VMCS32_RO_EXIT_REASON,
     637    VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO,
     638    VMX_VMCS32_RO_EXIT_INTERRUPTION_ERROR_CODE,
     639    VMX_VMCS32_RO_IDT_VECTORING_INFO,
     640    VMX_VMCS32_RO_IDT_VECTORING_ERROR_CODE,
     641    VMX_VMCS32_RO_EXIT_INSTR_LENGTH,
     642    VMX_VMCS32_RO_EXIT_INSTR_INFO,
     643
     644    /* 32-bit guest-state fields. */
     645    VMX_VMCS32_GUEST_ES_LIMIT,
     646    VMX_VMCS32_GUEST_CS_LIMIT,
     647    VMX_VMCS32_GUEST_SS_LIMIT,
     648    VMX_VMCS32_GUEST_DS_LIMIT,
     649    VMX_VMCS32_GUEST_FS_LIMIT,
     650    VMX_VMCS32_GUEST_GS_LIMIT,
     651    VMX_VMCS32_GUEST_LDTR_LIMIT,
     652    VMX_VMCS32_GUEST_TR_LIMIT,
     653    VMX_VMCS32_GUEST_GDTR_LIMIT,
     654    VMX_VMCS32_GUEST_IDTR_LIMIT,
     655    VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS,
     656    VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS,
     657    VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS,
     658    VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS,
     659    VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS,
     660    VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS,
     661    VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS,
     662    VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS,
     663    VMX_VMCS32_GUEST_INT_STATE,
     664    VMX_VMCS32_GUEST_ACTIVITY_STATE,
     665    VMX_VMCS32_GUEST_SMBASE,
     666    VMX_VMCS32_GUEST_SYSENTER_CS,
     667    VMX_VMCS32_PREEMPT_TIMER_VALUE,
     668
     669    /* 32-bit host-state fields. */
     670    VMX_VMCS32_HOST_SYSENTER_CS,
     671
     672    /* Natural-width control fields. */
     673    VMX_VMCS_CTRL_CR0_MASK,
     674    VMX_VMCS_CTRL_CR4_MASK,
     675    VMX_VMCS_CTRL_CR0_READ_SHADOW,
     676    VMX_VMCS_CTRL_CR4_READ_SHADOW,
     677    VMX_VMCS_CTRL_CR3_TARGET_VAL0,
     678    VMX_VMCS_CTRL_CR3_TARGET_VAL1,
     679    VMX_VMCS_CTRL_CR3_TARGET_VAL2,
     680    VMX_VMCS_CTRL_CR3_TARGET_VAL3,
     681
     682    /* Natural-width read-only data fields. */
     683    VMX_VMCS_RO_EXIT_QUALIFICATION,
     684    VMX_VMCS_RO_IO_RCX,
     685    VMX_VMCS_RO_IO_RSI,
     686    VMX_VMCS_RO_IO_RDI,
     687    VMX_VMCS_RO_IO_RIP,
     688    VMX_VMCS_RO_GUEST_LINEAR_ADDR,
     689
     690    /* Natural-width guest-state field */
     691    VMX_VMCS_GUEST_CR0,
     692    VMX_VMCS_GUEST_CR3,
     693    VMX_VMCS_GUEST_CR4,
     694    VMX_VMCS_GUEST_ES_BASE,
     695    VMX_VMCS_GUEST_CS_BASE,
     696    VMX_VMCS_GUEST_SS_BASE,
     697    VMX_VMCS_GUEST_DS_BASE,
     698    VMX_VMCS_GUEST_FS_BASE,
     699    VMX_VMCS_GUEST_GS_BASE,
     700    VMX_VMCS_GUEST_LDTR_BASE,
     701    VMX_VMCS_GUEST_TR_BASE,
     702    VMX_VMCS_GUEST_GDTR_BASE,
     703    VMX_VMCS_GUEST_IDTR_BASE,
     704    VMX_VMCS_GUEST_DR7,
     705    VMX_VMCS_GUEST_RSP,
     706    VMX_VMCS_GUEST_RIP,
     707    VMX_VMCS_GUEST_RFLAGS,
     708    VMX_VMCS_GUEST_PENDING_DEBUG_XCPTS,
     709    VMX_VMCS_GUEST_SYSENTER_ESP,
     710    VMX_VMCS_GUEST_SYSENTER_EIP,
     711
     712    /* Natural-width host-state fields */
     713    VMX_VMCS_HOST_CR0,
     714    VMX_VMCS_HOST_CR3,
     715    VMX_VMCS_HOST_CR4,
     716    VMX_VMCS_HOST_FS_BASE,
     717    VMX_VMCS_HOST_GS_BASE,
     718    VMX_VMCS_HOST_TR_BASE,
     719    VMX_VMCS_HOST_GDTR_BASE,
     720    VMX_VMCS_HOST_IDTR_BASE,
     721    VMX_VMCS_HOST_SYSENTER_ESP,
     722    VMX_VMCS_HOST_SYSENTER_EIP,
     723    VMX_VMCS_HOST_RSP,
     724    VMX_VMCS_HOST_RIP
     725};
     726#endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
     727
    491728#ifdef VMX_USE_CACHED_VMCS_ACCESSES
    492729static const uint32_t g_aVmcsCacheSegBase[] =
     
    13751612
    13761613
     1614#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     1615/**
     1616 * Initializes the shadow VMCS.
     1617 *
     1618 * This builds an array (for use later while executing a nested-guest) of VMCS
     1619 * fields to copy into the shadow VMCS.
     1620 *
     1621 * @param   pVM     The cross context VM structure.
     1622 */
     1623static void hmR0VmxInitShadowVmcsFieldsArray(PVM pVM)
     1624{
     1625    uint32_t const cVmcsFields = RT_ELEMENTS(g_aVmcsFields);
     1626    for (uint32_t i = 0; i < cVmcsFields; i++)
     1627    {
     1628        /*
     1629         * If the VMCS field depends on a CPU feature that is not exposed to the guest,
     1630         * we must not include it in the shadow VMCS fields array. Guests attempting to
     1631         * VMREAD/VMWRITE such VMCS fields would cause a VM-exit and we shall emulate
     1632         * the required behavior.
     1633         */
     1634        uint32_t const uVmcsField      = g_aVmcsFields[i];
     1635        bool const     fVmcsFieldValid = CPUMIsGuestVmxVmcsFieldValid(pVM, uVmcsField);
     1636        if (fVmcsFieldValid)
     1637        {
     1638            pVM->hm.s.vmx.paShadowVmcsFields[i] = uVmcsField;
     1639            ++pVM->hm.s.vmx.cShadowVmcsFields;
     1640        }
     1641    }
     1642}
     1643
     1644
     1645/**
     1646 * Initializes the VMREAD/VMWRITE bitmaps.
     1647 *
     1648 * @param   pVM                 The cross context VM structure.
     1649 */
     1650static void hmR0VmxInitVmreadVmwriteBitmaps(PVM pVM)
     1651{
     1652    /*
     1653     * By default, ensure guest attempts to acceses to any VMCS fields cause VM-exits.
     1654     */
     1655    uint32_t const  cbBitmap        = X86_PAGE_4K_SIZE;
     1656    uint8_t        *pbVmreadBitmap  = (uint8_t *)pVM->hm.s.vmx.pvVmreadBitmap;
     1657    uint8_t        *pbVmwriteBitmap = (uint8_t *)pVM->hm.s.vmx.pvVmwriteBitmap;
     1658    ASMMemFill32(pbVmreadBitmap,  cbBitmap, UINT32_C(0xffffffff));
     1659    ASMMemFill32(pbVmwriteBitmap, cbBitmap, UINT32_C(0xffffffff));
     1660
     1661    uint32_t const *paShadowVmcsFields = pVM->hm.s.vmx.paShadowVmcsFields;
     1662    uint32_t const  cShadowVmcsFields  = pVM->hm.s.vmx.cShadowVmcsFields;
     1663
     1664    /*
     1665     * Initialize the VMREAD bitmap.
     1666     * All valid guest VMCS fields (read-only and read-write) can be accessed
     1667     * using VMREAD without causing a VM-exit.
     1668     */
     1669    for (uint32_t i = 0; i < cShadowVmcsFields; i++)
     1670    {
     1671        uint32_t const uVmcsField = paShadowVmcsFields[i];
     1672        Assert(!(uVmcsField & VMX_VMCSFIELD_RSVD_MASK));
     1673        uint8_t *pbField = pbVmreadBitmap + (uVmcsField >> 3);
     1674        ASMBitClear(pbField, uVmcsField & 7);
     1675    }
     1676
     1677    /*
     1678     * Initialize the VMWRITE bitmap.
     1679     * Allow the guest to write to read-only guest VMCS fields only if the
     1680     * host CPU supports it, otherwise it would cause a VMWRITE instruction error.
     1681     */
     1682    bool const fHasVmwriteAll = RT_BOOL(pVM->hm.s.vmx.Msrs.u64Misc & VMX_MISC_VMWRITE_ALL);
     1683    for (uint32_t i = 0; i < cShadowVmcsFields; i++)
     1684    {
     1685        uint32_t const uVmcsField = paShadowVmcsFields[i];
     1686        if (   fHasVmwriteAll
     1687            || !HMVmxIsVmcsFieldReadOnly(uVmcsField))
     1688        {
     1689            Assert(!(uVmcsField & VMX_VMCSFIELD_RSVD_MASK));
     1690            uint8_t *pbField = pbVmwriteBitmap + (uVmcsField >> 3);
     1691            ASMBitClear(pbField, uVmcsField & 7);
     1692        }
     1693    }
     1694}
     1695#endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
     1696
     1697
    13771698/**
    13781699 * Allocates and maps a physically contiguous page. The allocated page is
     
    14331754
    14341755    Assert(pVmcsInfo->hMemObjVmcs          == NIL_RTR0MEMOBJ);
     1756    Assert(pVmcsInfo->hMemObjShadowVmcs    == NIL_RTR0MEMOBJ);
    14351757    Assert(pVmcsInfo->hMemObjMsrBitmap     == NIL_RTR0MEMOBJ);
    14361758    Assert(pVmcsInfo->hMemObjGuestMsrLoad  == NIL_RTR0MEMOBJ);
     
    14381760    Assert(pVmcsInfo->hMemObjHostMsrLoad   == NIL_RTR0MEMOBJ);
    14391761    pVmcsInfo->HCPhysVmcs          = NIL_RTHCPHYS;
     1762    pVmcsInfo->HCPhysShadowVmcs    = NIL_RTHCPHYS;
    14401763    pVmcsInfo->HCPhysMsrBitmap     = NIL_RTHCPHYS;
    14411764    pVmcsInfo->HCPhysGuestMsrLoad  = NIL_RTHCPHYS;
     
    14581781    hmR0VmxPageFree(&pVmcsInfo->hMemObjVmcs, &pVmcsInfo->pvVmcs, &pVmcsInfo->HCPhysVmcs);
    14591782
     1783    if (   pVM->cpum.ro.GuestFeatures.fVmx
     1784        && (pVM->hm.s.vmx.Msrs.ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_VMCS_SHADOWING))
     1785        hmR0VmxPageFree(&pVmcsInfo->hMemObjShadowVmcs, &pVmcsInfo->pvShadowVmcs, &pVmcsInfo->HCPhysShadowVmcs);
     1786
    14601787    if (pVM->hm.s.vmx.Msrs.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_MSR_BITMAPS)
    14611788        hmR0VmxPageFree(&pVmcsInfo->hMemObjMsrBitmap, &pVmcsInfo->pvMsrBitmap, &pVmcsInfo->HCPhysMsrBitmap);
     
    14871814        if (!fIsNstGstVmcs)
    14881815        {
    1489             /* Get the allocated virtual-APIC page from the virtual APIC device. */
    1490             if (   PDMHasApic(pVCpu->CTX_SUFF(pVM))
    1491                 && (pVM->hm.s.vmx.Msrs.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_TPR_SHADOW))
     1816            /* Allocate the shadow VMCS if supported by the CPU. */
     1817            if (   pVM->cpum.ro.GuestFeatures.fVmx
     1818                && (pVM->hm.s.vmx.Msrs.ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_VMCS_SHADOWING))
     1819                rc = hmR0VmxPageAllocZ(&pVmcsInfo->hMemObjShadowVmcs, &pVmcsInfo->pvShadowVmcs, &pVmcsInfo->HCPhysShadowVmcs);
     1820
     1821            if (RT_SUCCESS(rc))
    14921822            {
    1493                 rc = APICGetApicPageForCpu(pVCpu, &pVmcsInfo->HCPhysVirtApic, (PRTR0PTR)&pVmcsInfo->pbVirtApic,
    1494                                            NULL /* pR3Ptr */, NULL /* pRCPtr */);
     1823                /* Get the allocated virtual-APIC page from the virtual APIC device. */
     1824                if (   PDMHasApic(pVCpu->CTX_SUFF(pVM))
     1825                    && (pVM->hm.s.vmx.Msrs.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_TPR_SHADOW))
     1826                {
     1827                    rc = APICGetApicPageForCpu(pVCpu, &pVmcsInfo->HCPhysVirtApic, (PRTR0PTR)&pVmcsInfo->pbVirtApic,
     1828                                               NULL /* pR3Ptr */, NULL /* pRCPtr */);
     1829                }
    14951830            }
    14961831        }
    14971832        else
    14981833        {
     1834            /* We don't yet support exposing VMCS shadowing to the guest. */
     1835            Assert(pVmcsInfo->HCPhysShadowVmcs == NIL_RTHCPHYS);
     1836            Assert(!pVmcsInfo->pvShadowVmcs);
     1837
     1838            /* The host-physical address of the virtual-APIC page in guest memory is taken directly. */
    14991839            Assert(pVmcsInfo->HCPhysVirtApic == NIL_RTHCPHYS);
    15001840            Assert(!pVmcsInfo->pbVirtApic);
     
    15701910    hmR0VmxPageFree(&pVM->hm.s.vmx.hMemObjApicAccess, (PRTR0PTR)&pVM->hm.s.vmx.pbApicAccess, &pVM->hm.s.vmx.HCPhysApicAccess);
    15711911
     1912#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     1913    if (   pVM->cpum.ro.GuestFeatures.fVmx
     1914        && (pVM->hm.s.vmx.Msrs.ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_VMCS_SHADOWING))
     1915    {
     1916        RTMemFree(pVM->hm.s.vmx.paShadowVmcsFields);
     1917        hmR0VmxPageFree(&pVM->hm.s.vmx.hMemObjVmreadBitmap,  &pVM->hm.s.vmx.pvVmreadBitmap,  &pVM->hm.s.vmx.HCPhysVmreadBitmap);
     1918        hmR0VmxPageFree(&pVM->hm.s.vmx.hMemObjVmwriteBitmap, &pVM->hm.s.vmx.pvVmwriteBitmap, &pVM->hm.s.vmx.HCPhysVmwriteBitmap);
     1919    }
     1920#endif
     1921
    15721922    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    15731923    {
     
    16562006        }
    16572007    }
     2008
     2009#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     2010    /* Allocate the shadow VMCS fields array, VMREAD, VMWRITE bitmaps if VMCS shadowing supported by the CPU. */
     2011    if (   pVM->cpum.ro.GuestFeatures.fVmx
     2012        && (pVM->hm.s.vmx.Msrs.ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_VMCS_SHADOWING))
     2013    {
     2014        pVM->hm.s.vmx.paShadowVmcsFields = (uint32_t *)RTMemAllocZ(sizeof(g_aVmcsFields));
     2015        if (RT_LIKELY(pVM->hm.s.vmx.paShadowVmcsFields))
     2016        {
     2017            rc = hmR0VmxPageAllocZ(&pVM->hm.s.vmx.hMemObjVmreadBitmap, &pVM->hm.s.vmx.pvVmreadBitmap,
     2018                                   &pVM->hm.s.vmx.HCPhysVmreadBitmap);
     2019            if (RT_SUCCESS(rc))
     2020            {
     2021                rc = hmR0VmxPageAllocZ(&pVM->hm.s.vmx.hMemObjVmwriteBitmap, &pVM->hm.s.vmx.pvVmwriteBitmap,
     2022                                       &pVM->hm.s.vmx.HCPhysVmwriteBitmap);
     2023                if (RT_SUCCESS(rc))
     2024                {
     2025                    hmR0VmxInitShadowVmcsFieldsArray(pVM);
     2026                    hmR0VmxInitVmreadVmwriteBitmaps(pVM);
     2027                }
     2028            }
     2029        }
     2030        else
     2031            rc = VERR_NO_MEMORY;
     2032
     2033        if (RT_FAILURE(rc))
     2034        {
     2035            hmR0VmxStructsFree(pVM);
     2036            return rc;
     2037        }
     2038    }
     2039#endif
    16582040
    16592041    /*
     
    16922074}
    16932075
    1694 
    16952076#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    16962077/**
     
    17102091}
    17112092#endif
    1712 
    17132093
    17142094/**
     
    38444224
    38454225# ifdef VBOX_STRICT
    3846 static bool hmR0VmxIsValidWriteField(uint32_t idxField)
     4226static bool hmR0VmxIsValidWriteFieldInCache(uint32_t idxField)
    38474227{
    38484228    switch (idxField)
     
    38684248}
    38694249
    3870 static bool hmR0VmxIsValidReadField(uint32_t idxField)
     4250static bool hmR0VmxIsValidReadFieldInCache(uint32_t idxField)
    38714251{
    38724252    switch (idxField)
     
    38774257    }
    38784258    /* Remaining readable fields should also be writable. */
    3879     return hmR0VmxIsValidWriteField(idxField);
     4259    return hmR0VmxIsValidWriteFieldInCache(idxField);
    38804260}
    38814261# endif /* VBOX_STRICT */
     
    39024282#ifdef VBOX_STRICT
    39034283    for (uint32_t i = 0; i < pVCpu->hm.s.vmx.VmcsCache.Write.cValidEntries; i++)
    3904         Assert(hmR0VmxIsValidWriteField(pVCpu->hm.s.vmx.VmcsCache.Write.aField[i]));
     4284        Assert(hmR0VmxIsValidWriteFieldInCache(pVCpu->hm.s.vmx.VmcsCache.Write.aField[i]));
    39054285
    39064286    for (uint32_t i = 0; i <pVCpu->hm.s.vmx.VmcsCache.Read.cValidEntries; i++)
    3907         Assert(hmR0VmxIsValidReadField(pVCpu->hm.s.vmx.VmcsCache.Read.aField[i]));
     4287        Assert(hmR0VmxIsValidReadFieldInCache(pVCpu->hm.s.vmx.VmcsCache.Read.aField[i]));
    39084288#endif
    39094289
  • trunk/src/VBox/VMM/include/HMInternal.h

    r79123 r79202  
    528528        /** Set if VT-x VPID is allowed. */
    529529        bool                        fAllowVpid;
    530         /** Set if unrestricted guest execution is in use (real and protected mode without paging). */
     530        /** Set if unrestricted guest execution is in use (real and protected mode
     531         *  without paging). */
    531532        bool                        fUnrestrictedGuest;
    532533        /** Set if unrestricted guest execution is allowed to be used. */
     
    539540        /** Virtual address of the TSS page used for real mode emulation. */
    540541        R3PTRTYPE(PVBOXTSS)         pRealModeTSS;
    541         /** Virtual address of the identity page table used for real mode and protected mode without paging emulation in EPT mode. */
     542        /** Virtual address of the identity page table used for real mode and protected
     543         *  mode without paging emulation in EPT mode. */
    542544        R3PTRTYPE(PX86PD)           pNonPagingModeEPTPageTable;
    543545
     
    549551        R0PTRTYPE(uint8_t *)        pbApicAccess;
    550552
     553        /** Physical address of the VMREAD bitmap. */
     554        RTHCPHYS                    HCPhysVmreadBitmap;
     555        /** Ring-0 memory object for the VMREAD bitmap. */
     556        RTR0MEMOBJ                  hMemObjVmreadBitmap;
     557        /** Pointer to the VMREAD bitmap. */
     558        R0PTRTYPE(void *)           pvVmreadBitmap;
     559
     560        /** Physical address of the VMWRITE bitmap. */
     561        RTHCPHYS                    HCPhysVmwriteBitmap;
     562        /** Ring-0 memory object for the VMWRITE bitmap. */
     563        RTR0MEMOBJ                  hMemObjVmwriteBitmap;
     564        /** Pointer to the VMWRITE bitmap. */
     565        R0PTRTYPE(void *)           pvVmwriteBitmap;
     566
    551567#ifdef VBOX_WITH_CRASHDUMP_MAGIC
     568        /** Physical address of the crash-dump scratch area. */
    552569        RTHCPHYS                    HCPhysScratch;
     570        /** Ring-0 memory object for the crash-dump scratch area. */
    553571        RTR0MEMOBJ                  hMemObjScratch;
     572        /** Pointer to the crash-dump scratch bitmap. */
    554573        R0PTRTYPE(uint8_t *)        pbScratch;
    555574#endif
     
    583602        /** Host-physical address for a failing VMXON instruction. */
    584603        RTHCPHYS                    HCPhysVmxEnableError;
     604
     605        /** Pointer to the shadow VMCS fields array. */
     606        R0PTRTYPE(uint32_t *)       paShadowVmcsFields;
     607        RTR0PTR                     pvR0Alignment1;
     608        /** Number of elements in the shadow VMCS fields array. */
     609        uint32_t                    cShadowVmcsFields;
     610        uint32_t                    u32Alignemnt0;
    585611    } vmx;
    586612
     
    759785    /** Host-virtual address of the VMCS. */
    760786    R0PTRTYPE(void *)           pvVmcs;
     787
     788    /** Host-physical address of the shadow VMCS. */
     789    RTHCPHYS                    HCPhysShadowVmcs;
     790    /** R0 memory object for the shadow VMCS. */
     791    RTR0MEMOBJ                  hMemObjShadowVmcs;
     792    /** Host-virtual address of the shadow VMCS. */
     793    R0PTRTYPE(void *)           pvShadowVmcs;
    761794
    762795    /** Host-physical address of the virtual APIC page. */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette